1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-13 00:09:51 +02:00

See ChangeLog: Tue Dec 8 13:15:16 CET 1998 Werner Koch

This commit is contained in:
Werner Koch 1998-12-08 12:20:53 +00:00
parent df1326eb05
commit ab986970eb
36 changed files with 514 additions and 149 deletions

8
NEWS
View File

@ -3,6 +3,14 @@
other GnuPG processes won't damage these files. You other GnuPG processes won't damage these files. You
may want to put the option --lock-once into your options file. may want to put the option --lock-once into your options file.
* The latest self-signatures are now used; this enables --import
to see updated preferences etc.
* import of subkeys should now work.
* Random gathering modules may now be loaded as extensions. Add
such a module for most Unices but it is very experimental!
Noteworthy changes in version 0.4.4 Noteworthy changes in version 0.4.4
----------------------------------- -----------------------------------

View File

@ -25,3 +25,5 @@
Can "--dump-options" be used for this or should we place the Can "--dump-options" be used for this or should we place the
options in a special ELF segment? options in a special ELF segment?
* Split key support (n-out-of-m)

3
THANKS
View File

@ -1,4 +1,4 @@
GNUPG was originally written by Werner Koch. Other people contributed by GnuPG was originally written by Werner Koch. Other people contributed by
reporting problems, suggesting various improvements or submitting actual reporting problems, suggesting various improvements or submitting actual
code. Here is a list of those people. Help me keep it complete and free of code. Here is a list of those people. Help me keep it complete and free of
errors. errors.
@ -24,6 +24,7 @@ Frank Heckenbach heckenb@mi.uni-erlangen.de
Gaël Quéri gqueri@mail.dotcom.fr Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca Greg Louis glouis@dynamicro.on.ca
Gregory Steuck steuck@iname.com Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Hendrik Buschkamp buschkamp@rheumanet.org Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org Holger Schurig holger@d.om.org
Hugh Daniel hugh@toad.com Hugh Daniel hugh@toad.com

6
TODO
View File

@ -5,7 +5,7 @@
* preferences of hash algorithms are not yet used. * preferences of hash algorithms are not yet used.
* Check Berkeley BD - it is in glibc -any licensing problems? * Check Berkeley BD - it is in glibc - any licensing problems?
* I noticed, that we sometimes have only 3 items in a trustrecord, but * I noticed, that we sometimes have only 3 items in a trustrecord, but
a next pointer ro more records - check wehther the reuse code really a next pointer ro more records - check wehther the reuse code really
@ -23,10 +23,6 @@
* clearsig: keep lineendings as they are. Remember that trailings * clearsig: keep lineendings as they are. Remember that trailings
blanks are not hashed. blanks are not hashed.
* Always use the latest key signature (import). This is needed, so
that we are able to chnage the expiration time or other info in the
selfsignature
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but: * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
OpenBSD binaries are a.out, so every symbol begins with "_" OpenBSD binaries are a.out, so every symbol begins with "_"

View File

@ -300,3 +300,4 @@ zlib/Makefile
checks/Makefile checks/Makefile
]) ])
dnl *-*wedit:notab*-* Please keep this as the last line.

View File

@ -84,9 +84,9 @@ Record type 1:
-------------- --------------
Version information for this TrustDB. This is always the first Version information for this TrustDB. This is always the first
record of the DB and the only one with type 1. record of the DB and the only one with type 1.
1 byte value 2 1 byte value 1
3 bytes 'gpg' magic value 3 bytes 'gpg' magic value
1 byte Version of the TrustDB 1 byte Version of the TrustDB (2)
1 byte marginals needed 1 byte marginals needed
1 byte completes needed 1 byte completes needed
1 byte max_cert_depth 1 byte max_cert_depth

View File

@ -1,6 +1,6 @@
=head1 NAME =head1 NAME
gpg - GNU Privacy Guard gpg, gpgm - GNU Privacy Guard
=head1 SYNOPSIS =head1 SYNOPSIS
@ -10,7 +10,7 @@ B<gpgm> [--homedir name] [--options file] [options] command [args]
=head1 DESCRIPTION =head1 DESCRIPTION
B<gpg> is the main program for the GNUPG system. B<gpgm> is a maintenance B<gpg> is the main program for the GnuPG system. B<gpgm> is a maintenance
tool which has some commands B<gpgm> does not have; it is there because tool which has some commands B<gpgm> does not have; it is there because
it does not handle sensitive data and therefore has no need to allocate it does not handle sensitive data and therefore has no need to allocate
secure memory. secure memory.
@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
B<-kvc> List fingerprints B<-kvc> List fingerprints
B<-kvvc> List fingerprints and signatures B<-kvvc> List fingerprints and signatures
B<--list-keys> [I<names>] B<--list-keys> [I<names>]
List all keys from the public keyrings, or just the List all keys from the public keyrings, or just the
ones given on the command line. ones given on the command line.
@ -83,7 +83,7 @@ B<--list-secret-keys> [I<names>]
List all keys from the secret keyrings, or just the List all keys from the secret keyrings, or just the
ones given on the command line. ones given on the command line.
B<--list-sigs> [I<names>] B<--list-sigs> [I<names>]
Same as B<--list-keys>, but the signatures are listed Same as B<--list-keys>, but the signatures are listed
too. too.
@ -129,7 +129,7 @@ B<--edit-key> I<name>
B<delkey> B<delkey>
Remove a subkey. Remove a subkey.
B<expire> B<expire>
Change the key expiration time. If a key is Change the key expiration time. If a key is
select, the time of this key will be changed. select, the time of this key will be changed.
With no selection the key expiration of the With no selection the key expiration of the
primary key is changed. primary key is changed.
@ -190,7 +190,7 @@ B<--export-secret-keys> [I<names>
This is normally not very useful. This is normally not very useful.
B<--import>, B<--fast-import> B<--import>, B<--fast-import>
Import/merge keys. The fast version does not build Import/merge keys. The fast version does not build
the trustdb; this can be deon at anytime with the the trustdb; this can be deon at anytime with the
command B<--update-trustdb>. command B<--update-trustdb>.
@ -207,7 +207,7 @@ B<--import-ownertrust> [I<filename>]
Long options can be put in an options file (default F<~/.gnupg/options>); Long options can be put in an options file (default F<~/.gnupg/options>);
do not write the 2 dashes, but simply the name of the option and any do not write the 2 dashes, but simply the name of the option and any
arguments if required. Lines with a hash as the first non-white-space arguments if required. Lines with a hash as the first non-white-space
character are ignored. Commands may be put in this file too, but that character are ignored. Commands may be put in this file too, but that
does not make sense. does not make sense.
@ -230,6 +230,19 @@ B<--default-key> I<name>
is not used the default user-id is the first user-id is not used the default user-id is the first user-id
from the secret keyring. from the secret keyring.
B<--trusted-key> I<keyid>
Assume that the key with the I<keyid> (which must be
a full (8 byte) keyid) is as trustworthy as one of
your own secret keys. This may be used to make keys
valid which are not directly ceritified by you but
by a CA you trust. The advantage of this option is
that it shortens the path of certification.
You may also use this option to skip the verification
of your own secret keys which is normally done every
time GnuPG starts up: Use for I<keyid> the one of
your key.
B<-r> I<name>, B<--remote-user> I<name> B<-r> I<name>, B<--remote-user> I<name>
Use I<name> as the user-id for encryption. Use I<name> as the user-id for encryption.
This option is silently ignored for the list commands, This option is silently ignored for the list commands,
@ -252,7 +265,7 @@ B<-t>, B<--textmode>
B<--textmode>) is used together with armoring B<--textmode>) is used together with armoring
and signing, this enables clearsigned messages. and signing, this enables clearsigned messages.
This kludge is needed for PGP compatibility; This kludge is needed for PGP compatibility;
normally you would use B<--sign> or b<--clearsign> normally you would use B<--sign> or B<--clearsign>
to selected the type os signatures. to selected the type os signatures.
B<-n>, B<--dry-run> B<-n>, B<--dry-run>
@ -471,16 +484,16 @@ a signature was bad and other errorcode for fatal errors.
=head1 EXAMPLES =head1 EXAMPLES
-se -r Bob [file] sign and encrypt for user Bob -se -r Bob [file] sign and encrypt for user Bob
-sat [file] make a clear text signature -sat [file] make a clear text signature
-sb [file] make a detached signature -sb [file] make a detached signature
-k [userid] show keys -k [userid] show keys
-kc [userid] show fingerprint -kc [userid] show fingerprint
=head1 ENVIRONMENT =head1 ENVIRONMENT
C<HOME> Used to locate the default home directory. C<HOME> Used to locate the default home directory.
C<GNUPGHOME> If set, direcory used instead of F<~/.gnupg>. C<GNUPGHOME> If set directory used instead of F<~/.gnupg>.
=head1 FILES =head1 FILES
@ -493,13 +506,13 @@ F<~/.gnupg/pubring.gpg.lock> and the lock file
F<~/.gnupg/trustdb.gpg> The trust database F<~/.gnupg/trustdb.gpg> The trust database
F<~/.gnupg/trustdb.gpg.lock> and the lock file F<~/.gnupg/trustdb.gpg.lock> and the lock file
F<~/.gnupg/options> May contain options F<~/.gnupg/options> May contain options
F</usr[/local]/lib/gnupg/> Default location for extensions F</usr[/local]/lib/gnupg/> Default location for extensions
=head1 SEE ALSO =head1 SEE ALSO
gpg(1) gpgm(1) gpg(1) gpgm(1)
=head1 WARNINGS =head1 WARNINGS

View File

@ -1,3 +1,25 @@
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* trustdb.c (upd_uid_record): Now uses the newest self-signature
(insert_trust_record): Now calls update with recheck set to true.
(register_trusted_key): New.
(verify_own_keys): Enhanced by list of trusted keys.
* g10.c (main): Print a warning when a devel version is used.
(main): New option --trusted-key
* import.c (merge_blocks): Fixed merging of new user ids and
added merging of subkeys.
(append_uid): Ditto.
(merge_keysig): New.
(append_key): New.
* getkey.c (merge_one_pk_and_selfsig): Get the expiration time
from the newest self-signature.
(merge_keys_and_selfsig): Ditto.
* free-packet.c (cmp_secret_key): New.
Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de> Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* g10.c: New option --lock-once * g10.c: New option --lock-once

View File

@ -345,7 +345,7 @@ free_packet( PACKET *pkt )
} }
/**************** /****************
* Returns 0 if they match. * returns 0 if they match.
*/ */
int int
cmp_public_keys( PKT_public_key *a, PKT_public_key *b ) cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
@ -370,6 +370,33 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
return 0; return 0;
} }
/****************
* Returns 0 if they match.
* We only compare the public parts.
*/
int
cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
{
int n, i;
if( a->timestamp != b->timestamp )
return -1;
if( a->expiredate != b->expiredate )
return -1;
if( a->pubkey_algo != b->pubkey_algo )
return -1;
n = pubkey_get_npkey( b->pubkey_algo );
if( !n )
return -1; /* can't compare due to unknown algorithm */
for(i=0; i < n; i++ ) {
if( mpi_cmp( a->skey[i], b->skey[i] ) )
return -1;
}
return 0;
}
/**************** /****************
* Returns 0 if they match. * Returns 0 if they match.
*/ */

View File

@ -23,6 +23,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <unistd.h> #include <unistd.h>
#define MAINTAINER_OPTIONS #define MAINTAINER_OPTIONS
@ -107,6 +108,7 @@ enum cmd_and_opt_values { aNull = 0,
oKeyring, oKeyring,
oSecretKeyring, oSecretKeyring,
oDefaultKey, oDefaultKey,
oTrustedKey,
oOptions, oOptions,
oDebug, oDebug,
oDebugAll, oDebugAll,
@ -224,7 +226,7 @@ static ARGPARSE_OPTS opts[] = {
{ oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")},
{ oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
{ oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
{ oCharset, "charset" , 2, N_("|NAME| set terminal charset to NAME") }, { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
{ oOptions, "options" , 2, N_("read options from file")}, { oOptions, "options" , 2, N_("read options from file")},
{ oDebug, "debug" ,4|16, N_("set debugging flags")}, { oDebug, "debug" ,4|16, N_("set debugging flags")},
@ -234,6 +236,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")}, { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")}, { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
{ oMaxCertDepth, "max-cert-depth", 1, "@" }, { oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")}, { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")}, { oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
{ oS2KMode, "s2k-mode", 1, N_("|N|use passphrase mode N")}, { oS2KMode, "s2k-mode", 1, N_("|N|use passphrase mode N")},
@ -706,6 +709,7 @@ main( int argc, char **argv )
case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break; case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
case oTrustDBName: trustdb_name = pargs.r.ret_str; break; case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break; case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
case oNoOptions: break; /* no-options */ case oNoOptions: break; /* no-options */
case oHomedir: opt.homedir = pargs.r.ret_str; break; case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oNoBatch: opt.batch = 0; break; case oNoBatch: opt.batch = 0; break;
@ -837,6 +841,13 @@ main( int argc, char **argv )
log_error(_("invalid S2K mode; must be 0, 1 or 3\n")); log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
} }
{ const char *p = strusage(13);
for( ; *p && (isdigit(*p) || *p=='.'); p++ )
;
if( p )
log_info("NOTE: This is a development version!\n");
}
if( log_get_errorcount(0) ) if( log_get_errorcount(0) )
g10_exit(2); g10_exit(2);

View File

@ -383,23 +383,27 @@ classify_user_id( const char *name, u32 *keyid, byte *fprint,
else if( i == 32 || ( i == 33 && *s == '0' ) ) { /* md5 fingerprint */ else if( i == 32 || ( i == 33 && *s == '0' ) ) { /* md5 fingerprint */
if( i==33 ) if( i==33 )
s++; s++;
memset(fprint+16, 4, 0); if( fprint ) {
for(j=0; j < 16; j++, s+=2 ) { memset(fprint+16, 4, 0);
int c = hextobyte( s ); for(j=0; j < 16; j++, s+=2 ) {
if( c == -1 ) int c = hextobyte( s );
return 0; if( c == -1 )
fprint[j] = c; return 0;
fprint[j] = c;
}
} }
mode = 16; mode = 16;
} }
else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/ else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/
if( i==33 ) if( i==33 )
s++; s++;
for(j=0; j < 20; j++, s+=2 ) { if( fprint ) {
int c = hextobyte( s ); for(j=0; j < 20; j++, s+=2 ) {
if( c == -1 ) int c = hextobyte( s );
return 0; if( c == -1 )
fprint[j] = c; return 0;
fprint[j] = c;
}
} }
mode = 20; mode = 20;
} }
@ -693,6 +697,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
PKT_signature *sig; PKT_signature *sig;
KBNODE k; KBNODE k;
u32 kid[2]; u32 kid[2];
u32 sigdate = 0;
assert( knode->pkt->pkttype == PKT_PUBLIC_KEY assert( knode->pkt->pkttype == PKT_PUBLIC_KEY
|| knode->pkt->pkttype == PKT_PUBLIC_SUBKEY ); || knode->pkt->pkttype == PKT_PUBLIC_SUBKEY );
@ -709,6 +714,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
} }
else else
keyid_from_pk( pk, kid ); keyid_from_pk( pk, kid );
for(k=keyblock; k; k = k->next ) { for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SIGNATURE if( k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10 && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
@ -716,16 +722,22 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
&& sig->keyid[0] == kid[0] && sig->keyid[0] == kid[0]
&& sig->keyid[1] == kid[1] && sig->keyid[1] == kid[1]
&& sig->version > 3 ) { && sig->version > 3 ) {
/* okay this is (the first) self-signature which can be used /* okay this is a self-signature which can be used.
* We use the latest self-signature.
* FIXME: We should only use this if the signature is valid * FIXME: We should only use this if the signature is valid
* but this is time consuming - we must provide another * but this is time consuming - we must provide another
* way to handle this * way to handle this
*/ */
const byte *p; const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL ); p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
pk->expiredate = p? pk->timestamp + buffer_to_u32(p):0; ed = p? pk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
pk->expiredate = ed;
sigdate = sig->timestamp;
}
/* fixme: add usage etc. to pk */ /* fixme: add usage etc. to pk */
break;
} }
} }
} }
@ -742,6 +754,7 @@ merge_keys_and_selfsig( KBNODE keyblock )
PKT_signature *sig; PKT_signature *sig;
KBNODE k; KBNODE k;
u32 kid[2] = { 0, 0 }; u32 kid[2] = { 0, 0 };
u32 sigdate = 0;
for(k=keyblock; k; k = k->next ) { for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_PUBLIC_KEY if( k->pkt->pkttype == PKT_PUBLIC_KEY
@ -764,21 +777,28 @@ merge_keys_and_selfsig( KBNODE keyblock )
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10 && (sig=k->pkt->pkt.signature)->sig_class >= 0x10
&& sig->sig_class <= 0x30 && sig->version > 3 && sig->sig_class <= 0x30 && sig->version > 3
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) { && sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
/* okay this is (the first) self-signature which can be used /* okay this is a self-signature which can be used.
* FIXME: We should only use this if the signature is valid * FIXME: We should only use this if the signature is valid
* but this is time consuming - we must provide another * but this is time consuming - we must provide another
* way to handle this * way to handle this
*/ */
const byte *p; const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL ); p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
if( pk ) { if( pk ) {
pk->expiredate = p? pk->timestamp + buffer_to_u32(p):0; ed = p? pk->timestamp + buffer_to_u32(p):0;
/* fixme: add usage etc. */ if( sig->timestamp > sigdate ) {
pk = NULL; /* use only the first self signature */ pk->expiredate = ed;
sigdate = sig->timestamp;
}
} }
else { else {
sk->expiredate = p? sk->timestamp + buffer_to_u32(p):0; ed = p? sk->timestamp + buffer_to_u32(p):0;
sk = NULL; /* use only the first self signature */ if( sig->timestamp > sigdate ) {
sk->expiredate = ed;
sigdate = sig->timestamp;
}
} }
} }
} }

View File

@ -1,14 +1,14 @@
/* import.c /* import.c
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GNUPG. * This file is part of GnuPG.
* *
* GNUPG is free software; you can redistribute it and/or modify * GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* GNUPG is distributed in the hope that it will be useful, * GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
@ -64,8 +64,12 @@ static int merge_blocks( const char *fname, KBNODE keyblock_orig,
int *n_uids, int *n_sigs, int *n_subk ); int *n_uids, int *n_sigs, int *n_subk );
static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid ); const char *fname, u32 *keyid );
static int append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid );
static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid ); const char *fname, u32 *keyid );
static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid );
/**************** /****************
@ -683,7 +687,7 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
unode->flag |= 2; /* mark as invalid */ unode->flag |= 2; /* mark as invalid */
} }
unode->flag |= 1; /* mark that user-id checked */ unode->flag |= 1; /* mark that signature checked */
} }
} }
return 0; return 0;
@ -759,8 +763,6 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
* *
* o compare the signatures: If we already have this signature, check * o compare the signatures: If we already have this signature, check
* that they compare okay; if not, issue a warning and ask the user. * that they compare okay; if not, issue a warning and ask the user.
* FIXME: add the check that we don't have duplicate signatures and the
* warning in cases where the old/new signatures don't match.
* o Simply add the signature. Can't verify here because we may not have * o Simply add the signature. Can't verify here because we may not have
* the signature's public key yet; verification is done when putting it * the signature's public key yet; verification is done when putting it
* into the trustdb, which is done automagically as soon as this pubkey * into the trustdb, which is done automagically as soon as this pubkey
@ -799,20 +801,18 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
KBNODE n2 = clone_kbnode(node); KBNODE n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 ); insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1; n2->flag |= 1;
node->flag |= 1;
log_info_f(fname, _("key %08lX: revocation certificate added\n"), log_info_f(fname, _("key %08lX: revocation certificate added\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
} }
} }
} }
/* 2nd: try to merge new ones in */ /* 2nd: try to merge new certificates in */
for(onode=keyblock_orig->next; onode; onode=onode->next ) { for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) { if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
/* find the user id in the imported keyblock */ /* find the user id in the imported keyblock */
for(node=keyblock->next; node; node=node->next ) for(node=keyblock->next; node; node=node->next )
if( !(node->flag & 1) if( node->pkt->pkttype == PKT_USER_ID
&& node->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( onode->pkt->pkt.user_id, && !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) ) node->pkt->pkt.user_id ) )
break; break;
@ -826,15 +826,14 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
/* 3rd: add new user-ids */ /* 3rd: add new user-ids */
for(node=keyblock->next; node; node=node->next ) { for(node=keyblock->next; node; node=node->next ) {
if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) { if( node->pkt->pkttype == PKT_USER_ID) {
/* do we have this in the original keyblock */ /* do we have this in the original keyblock */
for(onode=keyblock_orig->next; onode; onode=onode->next ) for(onode=keyblock_orig->next; onode; onode=onode->next )
if( !(onode->flag & 1) if( onode->pkt->pkttype == PKT_USER_ID
&& onode->pkt->pkttype == PKT_USER_ID && !cmp_user_ids( onode->pkt->pkt.user_id,
&& cmp_user_ids( onode->pkt->pkt.user_id, node->pkt->pkt.user_id ) )
node->pkt->pkt.user_id ) )
break; break;
if( !node ) { /* this is a new user id: append */ if( !onode ) { /* this is a new user id: append */
rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid); rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid);
if( rc ) if( rc )
return rc; return rc;
@ -843,8 +842,62 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
} }
} }
/* 4th: add new subkeys */ /* merge subkey certifcates */
/* FIXME */ for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( !(onode->flag & 1)
&& ( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
/* find the subkey in the imported keyblock */
for(node=keyblock->next; node; node=node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& !cmp_public_keys( onode->pkt->pkt.public_key,
node->pkt->pkt.public_key ) )
break;
else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
&& !cmp_secret_keys( onode->pkt->pkt.secret_key,
node->pkt->pkt.secret_key ) )
break;
}
if( node ) { /* found: merge */
rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
if( rc )
return rc;
}
}
}
/* add new subkeys */
for(node=keyblock->next; node; node=node->next ) {
onode = NULL;
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
/* do we have this in the original keyblock? */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( onode->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& !cmp_public_keys( onode->pkt->pkt.public_key,
node->pkt->pkt.public_key ) )
break;
if( !onode ) { /* this is a new subkey: append */
rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
if( rc )
return rc;
++*n_subk;
}
}
else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
/* do we have this in the original keyblock? */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
&& !cmp_secret_keys( onode->pkt->pkt.secret_key,
node->pkt->pkt.secret_key ) )
break;
if( !onode ) { /* this is a new subkey: append */
rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
if( rc )
return rc;
++*n_subk;
}
}
}
return 0; return 0;
} }
@ -858,25 +911,43 @@ static int
append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid ) const char *fname, u32 *keyid )
{ {
KBNODE n; KBNODE n, n_where=NULL;
assert(node->pkt->pkttype == PKT_USER_ID ); 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 ) { if( node->next->pkt->pkttype == PKT_USER_ID ) {
log_error_f(fname, _("key %08lX: our copy has no self-signature\n"), log_error_f(fname, _("key %08lX: our copy has no self-signature\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
return G10ERR_GENERAL; return G10ERR_GENERAL;
} }
for( ;node && node->pkt->pkttype != PKT_USER_ID; node = node->next ) { /* find the position */
for( n = keyblock; n; n_where = n, n = n->next ) {
if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n->pkt->pkttype == PKT_SECRET_SUBKEY )
break;
}
if( !n )
n_where = NULL;
/* and append/insert */
while( node ) {
/* we add a clone to the original keyblock, because this /* we add a clone to the original keyblock, because this
* one is released first */ * one is released first */
n = clone_kbnode(node); n = clone_kbnode(node);
add_kbnode( keyblock, n ); if( n_where ) {
node->flag |= 1; insert_kbnode( n_where, n, 0 );
n_where = n;
}
else
add_kbnode( keyblock, n );
n->flag |= 1; n->flag |= 1;
node->flag |= 1;
if( n->pkt->pkttype == PKT_SIGNATURE ) if( n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs; ++*n_sigs;
node = node->next;
if( node && node->pkt->pkttype != PKT_SIGNATURE )
break;
} }
return 0; return 0;
@ -909,33 +980,113 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
if( n->pkt->pkttype != PKT_SIGNATURE ) if( n->pkt->pkttype != PKT_SIGNATURE )
continue; continue;
found = 0; found = 0;
for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next) for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
if( n2->pkt->pkttype == PKT_SIGNATURE if( n2->pkt->pkttype == PKT_SIGNATURE
&& n->pkt->pkt.signature->keyid[0] && n->pkt->pkt.signature->keyid[0]
== n2->pkt->pkt.signature->keyid[0] == n2->pkt->pkt.signature->keyid[0]
&& n->pkt->pkt.signature->keyid[1] && n->pkt->pkt.signature->keyid[1]
== n2->pkt->pkt.signature->keyid[1] ) { == n2->pkt->pkt.signature->keyid[1]
found++; && n->pkt->pkt.signature->timestamp
break; <= n2->pkt->pkt.signature->timestamp
&& n->pkt->pkt.signature->sig_class
== n2->pkt->pkt.signature->sig_class ) {
found++;
break;
}
} }
if( !found ) {
if( found ) { /* we already have this signature */ /* This signature is new or newer, append N to DST.
/* Hmmm: should we compare the timestamp etc? * We add a clone to the original keyblock, because this
* but then we have first to see whether this signature is valid * one is released first */
* - or simply add it in such a case and let trustdb logic n2 = clone_kbnode(n);
* decide whether to remove the old one insert_kbnode( dst, n2, PKT_SIGNATURE );
*/ n2->flag |= 1;
continue; n->flag |= 1;
++*n_sigs;
} }
}
/* This signature is new, append N to DST it.
* We add a clone to the original keyblock, because this return 0;
* one is released first */ }
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE ); /****************
n2->flag |= 1; * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
n->flag |= 1; */
++*n_sigs; static int
merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n, n2;
int found=0;
assert( dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| dst->pkt->pkttype == PKT_SECRET_SUBKEY );
for(n=src->next; n ; n = n->next ) {
if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n->pkt->pkttype == PKT_PUBLIC_KEY )
break;
if( n->pkt->pkttype != PKT_SIGNATURE )
continue;
found = 0;
for(n2=dst->next; n2; n2 = n2->next){
if( n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| n2->pkt->pkttype == PKT_PUBLIC_KEY )
break;
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]
&& n->pkt->pkt.signature->timestamp
<= n2->pkt->pkt.signature->timestamp
&& n->pkt->pkt.signature->sig_class
== n2->pkt->pkt.signature->sig_class ) {
found++;
break;
}
}
if( !found ) {
/* This signature is new or newer, append N to DST.
* We add a clone to the original keyblock, because this
* one is released first */
n2 = clone_kbnode(n);
insert_kbnode( dst, n2, PKT_SIGNATURE );
n2->flag |= 1;
n->flag |= 1;
++*n_sigs;
}
}
return 0;
}
/****************
* append the subkey starting with NODE and all signatures to KEYBLOCK.
* Mark all new and copied packets by setting flag bit 0.
*/
static int
append_key( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n;
assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
|| node->pkt->pkttype == PKT_SECRET_SUBKEY );
while( node ) {
/* we add a clone to the original keyblock, because this
* one is released first */
n = clone_kbnode(node);
add_kbnode( keyblock, n );
n->flag |= 1;
node->flag |= 1;
if( n->pkt->pkttype == PKT_SIGNATURE )
++*n_sigs;
node = node->next;
if( node && node->pkt->pkttype != PKT_SIGNATURE )
break;
} }
return 0; return 0;

View File

@ -614,7 +614,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands )
if( !stricmp( answer, cmds[i].name ) ) if( !stricmp( answer, cmds[i].name ) )
break; break;
if( cmds[i].need_sk && !sec_keyblock ) { if( cmds[i].need_sk && !sec_keyblock ) {
tty_printf(_("Need the secret key to to this.\n")); tty_printf(_("Need the secret key to do this.\n"));
cmd = cmdNOP; cmd = cmdNOP;
} }
else else

View File

@ -272,7 +272,8 @@ PKT_public_key *copy_public_key_new_namehash( PKT_public_key *d,
PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s ); PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s ); PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s ); PKT_user_id *copy_user_id( PKT_user_id *d, PKT_user_id *s );
int cmp_public_keys( PKT_public_key *d, PKT_public_key *s ); int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
int cmp_signatures( PKT_signature *a, PKT_signature *b ); int cmp_signatures( PKT_signature *a, PKT_signature *b );
int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk ); int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );

View File

@ -230,7 +230,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
if( create && !pass ) { if( create && !pass ) {
randomize_buffer(s2k->salt, 8, 1); randomize_buffer(s2k->salt, 8, 1);
if( s2k->mode == 3 ) if( s2k->mode == 3 )
s2k->count = 96; /* = 56536 */ s2k->count = 96; /* 65536 iterations */
} }
if( s2k->mode == 3 ) { if( s2k->mode == 3 ) {

View File

@ -46,6 +46,11 @@
#error Must change structure of trustdb #error Must change structure of trustdb
#endif #endif
struct keyid_list {
struct keyid_list *next;
u32 keyid[2];
};
struct local_id_item { struct local_id_item {
struct local_id_item *next; struct local_id_item *next;
ulong lid; ulong lid;
@ -102,9 +107,10 @@ static void upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
TRUSTREC *drec, RECNO_LIST *recno_list, int recheck, TRUSTREC *drec, RECNO_LIST *recno_list, int recheck,
TRUSTREC *urec, const byte *uidhash, int revoke ); TRUSTREC *urec, const byte *uidhash, int revoke );
static struct keyid_list *trusted_key_list;
/* a table used to keep track of ultimately trusted keys /* a table used to keep track of ultimately trusted keys
* which are the ones from our secrings */ * which are the ones from our secrings and the trusted keys */
static LOCAL_ID_TABLE ultikey_table; static LOCAL_ID_TABLE ultikey_table;
/* list of unused lid items and tables */ /* list of unused lid items and tables */
@ -438,8 +444,30 @@ trust_letter( unsigned value )
} }
} }
void
register_trusted_key( const char *string )
{
u32 keyid[2];
struct keyid_list *r;
if( classify_user_id( string, keyid, NULL, NULL, NULL ) != 11 ) {
log_error(_("'%s' is not a valid long keyID\n"), string );
return;
}
for( r = trusted_key_list; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] )
return;
r = m_alloc( sizeof *r );
r->keyid[0] = keyid[0];
r->keyid[1] = keyid[1];
r->next = trusted_key_list;
trusted_key_list = r;
}
/**************** /****************
* Verify that all our public keys are in the trustDB. * Verify that all our public keys are in the trustdb.
*/ */
static int static int
verify_own_keys() verify_own_keys()
@ -449,8 +477,48 @@ verify_own_keys()
PKT_secret_key *sk = m_alloc_clear( sizeof *sk ); PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
PKT_public_key *pk = m_alloc_clear( sizeof *pk ); PKT_public_key *pk = m_alloc_clear( sizeof *pk );
u32 keyid[2]; u32 keyid[2];
struct keyid_list *kl;
/* put the trusted keys into the trusted key table */
for( kl = trusted_key_list; kl; kl = kl->next ) {
keyid[0] = kl->keyid[0];
keyid[1] = kl->keyid[1];
/* get the public key */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
if( rc ) {
log_info(_("key %08lX: no public key for trusted key - skipped\n"),
(ulong)keyid[1] );
}
else {
/* make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 ) { /* put it into the trustdb */
rc = insert_trust_record( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
}
}
else if( rc ) {
log_error(_("key %08lX: query record failed\n"),
(ulong)keyid[1] );
}
else {
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]);
else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]);
}
}
release_public_key_parts( pk );
}
while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) { while( !(rc=enum_secret_keys( &enum_context, sk, 0 ) ) ) {
int have_pk = 0;
keyid_from_sk( sk, keyid ); keyid_from_sk( sk, keyid );
if( DBG_TRUST ) if( DBG_TRUST )
@ -460,6 +528,11 @@ verify_own_keys()
log_info(_("NOTE: secret key %08lX is NOT protected.\n"), log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
(ulong)keyid[1] ); (ulong)keyid[1] );
for( kl = trusted_key_list; kl; kl = kl->next ) {
if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
goto skip; /* already in trusted key table */
}
/* see whether we can access the public key of this secret key */ /* see whether we can access the public key of this secret key */
memset( pk, 0, sizeof *pk ); memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid ); rc = get_pubkey( pk, keyid );
@ -468,6 +541,7 @@ verify_own_keys()
(ulong)keyid[1] ); (ulong)keyid[1] );
goto skip; goto skip;
} }
have_pk=1;
if( cmp_public_secret_key( pk, sk ) ) { if( cmp_public_secret_key( pk, sk ) ) {
log_info(_("key %08lX: secret and public key don't match\n"), log_info(_("key %08lX: secret and public key don't match\n"),
@ -495,20 +569,30 @@ verify_own_keys()
log_debug("key %08lX.%lu: stored into ultikey_table\n", log_debug("key %08lX.%lu: stored into ultikey_table\n",
(ulong)keyid[1], pk->local_id ); (ulong)keyid[1], pk->local_id );
if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) ) if( ins_lid_table_item( ultikey_table, pk->local_id, 0 ) )
log_error(_("key %08lX: already in secret key table\n"), log_error(_("key %08lX: already in trusted key table\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
else if( opt.verbose > 1 ) else if( opt.verbose > 1 )
log_info(_("key %08lX: accepted as secret key.\n"), log_info(_("key %08lX: accepted as trusted key.\n"),
(ulong)keyid[1]); (ulong)keyid[1]);
skip: skip:
release_secret_key_parts( sk ); release_secret_key_parts( sk );
release_public_key_parts( pk ); if( have_pk )
release_public_key_parts( pk );
} }
if( rc != -1 ) if( rc != -1 )
log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) ); log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) );
else else
rc = 0; rc = 0;
/* release the trusted keyid table */
{ struct keyid_list *kl2;
for( kl = trusted_key_list; kl; kl = kl2 ) {
kl2 = kl->next;
m_free( kl );
}
trusted_key_list = NULL;
}
enum_secret_keys( &enum_context, NULL, 0 ); /* free context */ enum_secret_keys( &enum_context, NULL, 0 ); /* free context */
free_secret_key( sk ); free_secret_key( sk );
free_public_key( pk ); free_public_key( pk );
@ -1727,7 +1811,7 @@ get_dir_record( PKT_public_key *pk, TRUSTREC *rec )
/**************** /****************
* This function simply looks for the key in the trustdb * This function simply looks for the key in the trustdb
* and makes sure that pk->local_id is set to the coreect value. * and makes sure that pk->local_id is set to the correct value.
* Return: 0 = found * Return: 0 = found
* -1 = not found * -1 = not found
* other = error * other = error
@ -2282,6 +2366,9 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID; urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
if( !selfsig ) if( !selfsig )
selfsig = sig; /* use the first valid sig */ selfsig = sig; /* use the first valid sig */
else if( sig->timestamp > selfsig->timestamp
&& sig->sig_class >= selfsig->sig_class )
selfsig = sig; /* but this one is newer */
} }
else { else {
log_info( "uid %08lX/%02X%02X: %s: %s\n", log_info( "uid %08lX/%02X%02X: %s: %s\n",
@ -2293,7 +2380,13 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
} }
else if( sig->sig_class == 0x30 ) { /* cert revocation */ else if( sig->sig_class == 0x30 ) { /* cert revocation */
rc = check_key_signature( keyblock, node, NULL ); rc = check_key_signature( keyblock, node, NULL );
if( !rc ) { if( !rc && selfsig && selfsig->timestamp > sig->timestamp ) {
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
(ulong)keyid[1], lid, uidhash[18], uidhash[19],
_("Valid user ID revocation skipped "
"due to a newer self signature\n") );
}
else if( !rc ) {
if( opt.verbose ) if( opt.verbose )
log_info( "uid %08lX.%lu/%02X%02X: %s\n", log_info( "uid %08lX.%lu/%02X%02X: %s\n",
(ulong)keyid[1], lid, uidhash[18], uidhash[19], (ulong)keyid[1], lid, uidhash[18], uidhash[19],
@ -2569,11 +2662,13 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
rec.r.sig.sig[i].flag |= SIGF_REVOKED; rec.r.sig.sig[i].flag |= SIGF_REVOKED;
} }
else if( rc == G10ERR_NO_PUBKEY ) { else if( rc == G10ERR_NO_PUBKEY ) {
#if 0 /* fixme: For some reason this really happens? */
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) ) if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n", log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
(ulong)keyid[1], lid, uidhash[18], (ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1], uidhash[19], (ulong)sig->keyid[1],
_("Hmmm, public key lost?") ); _("Hmmm, public key lost?") );
#endif
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY; rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
if( revoke ) if( revoke )
rec.r.sig.sig[i].flag |= SIGF_REVOKED; rec.r.sig.sig[i].flag |= SIGF_REVOKED;
@ -2918,7 +3013,7 @@ insert_trust_record( PKT_public_key *pk )
} }
/* and put all the other stuff into the keydb */ /* and put all the other stuff into the keydb */
rc = update_trust_record( keyblock, 0, NULL ); rc = update_trust_record( keyblock, 1, NULL );
if( !rc ) if( !rc )
process_hintlist( hintlist, dirrec.r.dir.lid ); process_hintlist( hintlist, dirrec.r.dir.lid );

View File

@ -45,6 +45,7 @@ void list_trustdb(const char *username);
void list_trust_path( const char *username ); void list_trust_path( const char *username );
void export_ownertrust(void); void export_ownertrust(void);
void import_ownertrust(const char *fname); void import_ownertrust(const char *fname);
void register_trusted_key( const char *string );
void check_trustdb( const char *username ); void check_trustdb( const char *username );
void update_trustdb( void ); void update_trustdb( void );
int init_trustdb( int level, const char *dbname ); int init_trustdb( int level, const char *dbname );

View File

@ -1,3 +1,8 @@
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* mpi.h (MPI): Changed the structure name to gcry_mpi and
changed all users.
Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de) Tue Oct 20 11:40:00 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.h (iobuf_get_temp_buffer): New. * iobuf.h (iobuf_get_temp_buffer): New.

View File

@ -43,7 +43,7 @@ int mpi_debug_mode;
typedef unsigned long int mpi_limb_t; typedef unsigned long int mpi_limb_t;
typedef signed long int mpi_limb_signed_t; typedef signed long int mpi_limb_signed_t;
typedef struct mpi_struct { struct gcry_mpi {
int alloced; /* array size (# of allocated limbs) */ int alloced; /* array size (# of allocated limbs) */
int nlimbs; /* number of valid limbs */ int nlimbs; /* number of valid limbs */
int nbits; /* the real number of valid bits (info only) */ int nbits; /* the real number of valid bits (info only) */
@ -52,7 +52,9 @@ typedef struct mpi_struct {
/* bit 1: the mpi is encrypted */ /* bit 1: the mpi is encrypted */
/* bit 2: the limb is a pointer to some m_alloced data */ /* bit 2: the limb is a pointer to some m_alloced data */
mpi_limb_t *d; /* array with the limbs */ mpi_limb_t *d; /* array with the limbs */
} *MPI; };
typedef struct gcry_mpi *MPI;
#define MPI_NULL NULL #define MPI_NULL NULL

View File

@ -1,3 +1,8 @@
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Moved the case for powerpc*linux
* powerpcp32/*.S: Removed some underscores.
Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de> Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
* config.links: Support for ppc with ELF * config.links: Support for ppc with ELF

View File

@ -124,6 +124,12 @@ case "${target}" in
path="m68k/mc68020 m68k" path="m68k/mc68020 m68k"
;; ;;
powerpc*-*-linux*)
echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
path="powerpc32"
;;
rs6000-*-aix[456789]* | rs6000-*-aix3.2.[456789]) rs6000-*-aix[456789]* | rs6000-*-aix3.2.[456789])
mpi_sflags="-Wa,-mpwr" mpi_sflags="-Wa,-mpwr"
path="power" path="power"
@ -146,12 +152,6 @@ case "${target}" in
mpi_sflags="-Wa,-mppc" mpi_sflags="-Wa,-mppc"
path="powerpc64" path="powerpc64"
;; ;;
powerpc*-*-linux*)
echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>asm-syntax.h
cat $srcdir/powerpc32/syntax.h >>./mpi/asm-syntax.h
path="powerpc32"
;;
*) *)
echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h

View File

@ -1,4 +1,4 @@
/* mpiutilac - Utility functions for MPI /* mpiutil.ac - Utility functions for MPI
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GNUPG. * This file is part of GNUPG.
@ -367,7 +367,7 @@ mpi_alloc_set_ui( unsigned long u)
void void
mpi_swap( MPI a, MPI b) mpi_swap( MPI a, MPI b)
{ {
struct mpi_struct tmp; struct gcry_mpi tmp;
tmp = *a; *a = *b; *b = tmp; tmp = *a; *a = *b; *b = tmp;
} }

View File

@ -48,7 +48,7 @@ mpihelp_add_n:
mtctr 6 # copy size into CTR mtctr 6 # copy size into CTR
lwz 8,0(4) # load least significant s1 limb lwz 8,0(4) # load least significant s1 limb
lwz 0,0(5) # load least significant s2 limb lwz 0,0(5) # load least significant s2 limb
addi 3,3,-4 # offset res_ptr, it's updated before used addi 3,3,-4 # offset res_ptr, it is updated before used
addc 7,0,8 # add least significant limbs, set cy addc 7,0,8 # add least significant limbs, set cy
bdz Lend # If done, skip loop bdz Lend # If done, skip loop
Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
@ -93,7 +93,7 @@ Lend: stw 7,4(3) # store ultimate result limb
possible 2-unrolled inner loop will not be. Also, watch out for the possible 2-unrolled inner loop will not be. Also, watch out for the
alignment... */ alignment... */
EALIGN(_mpihelp_add_n,3,0) EALIGN(mpihelp_add_n,3,0)
/* Set up for loop below. */ /* Set up for loop below. */
mtcrf 0x01,%r6 mtcrf 0x01,%r6
srwi. %r7,%r6,1 srwi. %r7,%r6,1
@ -131,6 +131,6 @@ EALIGN(_mpihelp_add_n,3,0)
/* Return the carry. */ /* Return the carry. */
1: addze %r3,%r10 1: addze %r3,%r10
blr blr
END(_mpihelp_add_n) END(mpihelp_add_n)
#endif #endif

View File

@ -96,7 +96,7 @@ Lend2: slw 0,10,6
/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize, /* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
unsigned int cnt) */ unsigned int cnt) */
EALIGN(_mpihelp_lshift,3,0) EALIGN(mpihelp_lshift,3,0)
mtctr %r5 # copy size into CTR mtctr %r5 # copy size into CTR
cmplwi %cr0,%r5,16 # is size < 16 cmplwi %cr0,%r5,16 # is size < 16
slwi %r0,%r5,2 slwi %r0,%r5,2
@ -194,5 +194,5 @@ L(end2):slw %r0,%r10,%r6
DO_LSHIFT(30) DO_LSHIFT(30)
DO_LSHIFT(31) DO_LSHIFT(31)
END(_mpihelp_lshift) END(mpihelp_lshift)
#endif #endif

View File

@ -95,7 +95,7 @@ Lend: stw 7,4(3)
mp_size_t s1_size, mp_limb_t s2_limb) mp_size_t s1_size, mp_limb_t s2_limb)
Calculate s1*s2 and put result in res_ptr; return carry. */ Calculate s1*s2 and put result in res_ptr; return carry. */
ENTRY(_mpihelp_mul_1) ENTRY(mpihelp_mul_1)
mtctr %r5 mtctr %r5
lwz %r0,0(%r4) lwz %r0,0(%r4)
@ -115,5 +115,5 @@ ENTRY(_mpihelp_mul_1)
1: stw %r7,4(%r3) 1: stw %r7,4(%r3)
addze %r3,%r10 addze %r3,%r10
blr blr
END(_mpihelp_mul_1) END(mpihelp_mul_1)
#endif #endif

View File

@ -99,7 +99,7 @@ Lend: stw 8,4(3)
/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr, /* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
mp_size_t s1_size, mp_limb_t s2_limb) mp_size_t s1_size, mp_limb_t s2_limb)
Calculate res+s1*s2 and put result back in res; return carry. */ Calculate res+s1*s2 and put result back in res; return carry. */
ENTRY(_mpihelp_addmul_1) ENTRY(mpihelp_addmul_1)
mtctr %r5 mtctr %r5
lwz %r0,0(%r4) lwz %r0,0(%r4)
@ -123,5 +123,5 @@ ENTRY(_mpihelp_addmul_1)
1: stw %r8,4(%r3) 1: stw %r8,4(%r3)
addze %r3,%r10 addze %r3,%r10
blr blr
END(_mpihelp_addmul_1) END(mpihelp_addmul_1)
#endif #endif

View File

@ -100,7 +100,7 @@ Lend: stw 8,4(3)
mp_size_t s1_size, mp_limb_t s2_limb) mp_size_t s1_size, mp_limb_t s2_limb)
Calculate res-s1*s2 and put result back in res; return carry. */ Calculate res-s1*s2 and put result back in res; return carry. */
ENTRY(_mpihelp_submul_1) ENTRY(mpihelp_submul_1)
mtctr %r5 mtctr %r5
lwz %r0,0(%r4) lwz %r0,0(%r4)
@ -126,5 +126,5 @@ ENTRY(_mpihelp_submul_1)
1: stw %r8,4(%r3) 1: stw %r8,4(%r3)
addze %r3,%r10 addze %r3,%r10
blr blr
END(_mpihelp_submul_1) END(mpihelp_submul_1)
#endif #endif

View File

@ -99,7 +99,7 @@ Lend2: srw 0,10,6
size r5 size r5
cnt r6 */ cnt r6 */
ENTRY(_mpihelp_rshift) ENTRY(mpihelp_rshift)
mtctr 5 # copy size into CTR mtctr 5 # copy size into CTR
addi 7,3,-4 # move adjusted res_ptr to free return reg addi 7,3,-4 # move adjusted res_ptr to free return reg
subfic 8,6,32 subfic 8,6,32
@ -127,5 +127,5 @@ ENTRY(_mpihelp_rshift)
2: srw 0,10,6 2: srw 0,10,6
stw 0,4(7) stw 0,4(7)
blr blr
END(_mpihelp_rshift) END(mpihelp_rshift)
#endif #endif

View File

@ -49,7 +49,7 @@ mpihelp_sub_n:
mtctr 6 # copy size into CTR mtctr 6 # copy size into CTR
lwz 8,0(4) # load least significant s1 limb lwz 8,0(4) # load least significant s1 limb
lwz 0,0(5) # load least significant s2 limb lwz 0,0(5) # load least significant s2 limb
addi 3,3,-4 # offset res_ptr, it's updated before used addi 3,3,-4 # offset res_ptr, it is updated before used
subfc 7,0,8 # add least significant limbs, set cy subfc 7,0,8 # add least significant limbs, set cy
bdz Lend # If done, skip loop bdz Lend # If done, skip loop
Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
@ -90,7 +90,7 @@ Lend: stw 7,4(3) # store ultimate result limb
possible 2-unrolled inner loop will not be. Also, watch out for the possible 2-unrolled inner loop will not be. Also, watch out for the
alignment... */ alignment... */
EALIGN(_mpihelp_sub_n,3,1) EALIGN(mpihelp_sub_n,3,1)
/* Set up for loop below. */ /* Set up for loop below. */
mtcrf 0x01,%r6 mtcrf 0x01,%r6
srwi. %r7,%r6,1 srwi. %r7,%r6,1
@ -128,5 +128,5 @@ EALIGN(_mpihelp_sub_n,3,1)
1: subfe %r3,%r3,%r3 1: subfe %r3,%r3,%r3
neg %r3,%r3 neg %r3,%r3
blr blr
END(_mpihelp_sub_n) END(mpihelp_sub_n)
#endif #endif

View File

@ -44,11 +44,11 @@
/* No profiling of gmp's assembly for now... */ /* No profiling of gmp's assembly for now... */
#define CALL_MCOUNT /* no profiling */ #define CALL_MCOUNT /* no profiling */
#define ENTRY(name) \ #define ENTRY(name) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(2); \ .align ALIGNARG(2); \
C_LABEL(name) \ C_LABEL(name) \
CALL_MCOUNT CALL_MCOUNT
#define EALIGN_W_0 /* No words to insert. */ #define EALIGN_W_0 /* No words to insert. */
@ -62,14 +62,14 @@
/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
past a 2^align boundary. */ past a 2^align boundary. */
#define EALIGN(name, alignt, words) \ #define EALIGN(name, alignt, words) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(alignt); \ .align ALIGNARG(alignt); \
EALIGN_W_##words; \ EALIGN_W_##words; \
C_LABEL(name) C_LABEL(name)
#undef END #undef END
#define END(name) \ #define END(name) \
ASM_SIZE_DIRECTIVE(name) ASM_SIZE_DIRECTIVE(name)

View File

@ -218,7 +218,7 @@ msgid "you found a bug ... (%s:%d)\n"
msgstr "Sie haben eine Wanze (Programmfehler) gefunden ... (%s:%d)\n" msgstr "Sie haben eine Wanze (Programmfehler) gefunden ... (%s:%d)\n"
#: cipher/rand-dummy.c:112 #: cipher/rand-dummy.c:112
#, #,
msgid "WARNING: using insecure random number generator!!\n" msgid "WARNING: using insecure random number generator!!\n"
msgstr "Der Zufallszahlengenerator erzeugt keine echten Zufallszahlen!\n" msgstr "Der Zufallszahlengenerator erzeugt keine echten Zufallszahlen!\n"
@ -257,12 +257,12 @@ msgstr ""
" " " "
#: g10/g10.c:158 #: g10/g10.c:158
#, #,
msgid "|[file]|make a signature" msgid "|[file]|make a signature"
msgstr "|[file]|Eine Unterschrift erzeugen" msgstr "|[file]|Eine Unterschrift erzeugen"
#: g10/g10.c:159 #: g10/g10.c:159
#, #,
msgid "|[file]|make a clear text signature" msgid "|[file]|make a clear text signature"
msgstr "|[file]|Eine Klartextunterschrift erzeugen" msgstr "|[file]|Eine Klartextunterschrift erzeugen"
@ -808,7 +808,7 @@ msgid ""
msgstr "" msgstr ""
"Bitte entscheiden Sie, in wieweit Sie diesem User zutrauen,\n" "Bitte entscheiden Sie, in wieweit Sie diesem User zutrauen,\n"
"den Schlüssel eines anderen Users korrekt zu prüfen (Vergleich mit\n" "den Schlüssel eines anderen Users korrekt zu prüfen (Vergleich mit\n"
"Lictbildausweisen, Vergleich der Fingerabdrücke aus unterschiedlichen\n" "Lictbildausweisen, Vergleich der Fingerabdrücke aus unterschiedlichen\n"
"Quellen ...)?\n" "Quellen ...)?\n"
"\n" "\n"
" 1 = Weiß nicht so recht\n" " 1 = Weiß nicht so recht\n"
@ -1964,7 +1964,7 @@ msgid "Command> "
msgstr "Befehl> " msgstr "Befehl> "
#: g10/keyedit.c:617 #: g10/keyedit.c:617
msgid "Need the secret key to to this.\n" msgid "Need the secret key to do this.\n"
msgstr "Hierzu wird der geheime Schlüssel benötigt.\n" msgstr "Hierzu wird der geheime Schlüssel benötigt.\n"
#: g10/keyedit.c:638 #: g10/keyedit.c:638
@ -2731,7 +2731,7 @@ msgid "lid %lu: insert failed: %s\n"
msgstr "lid %lu: Einfügen fehlgeschlagen: %s\n" msgstr "lid %lu: Einfügen fehlgeschlagen: %s\n"
#: g10/trustdb.c:1391 #: g10/trustdb.c:1391
#, c-format #, c-format
msgid "lid %lu: inserted\n" msgid "lid %lu: inserted\n"
msgstr "lid %lu: eingefügt\n" msgstr "lid %lu: eingefügt\n"
@ -2978,7 +2978,7 @@ msgid ""
"skipped '%s': this is a PGP generated ElGamal key which is not secure for " "skipped '%s': this is a PGP generated ElGamal key which is not secure for "
"signatures!\n" "signatures!\n"
msgstr "" msgstr ""
"'%s übersprungen: Dies ist ein durch PGP erzeugter ElGamal-Schlüssel. " "'%s übersprungen: Dies ist ein durch PGP erzeugter ElGamal-Schlüssel. "
"Das ist für Signaturen NICHT sicher genug!\n" "Das ist für Signaturen NICHT sicher genug!\n"
#: g10/status.c:246 #: g10/status.c:246

View File

@ -1951,7 +1951,7 @@ msgid "Command> "
msgstr "Comando> " msgstr "Comando> "
#: g10/keyedit.c:617 #: g10/keyedit.c:617
msgid "Need the secret key to to this.\n" msgid "Need the secret key to do this.\n"
msgstr "Se necesita la clave secreta para hacer esto\n" msgstr "Se necesita la clave secreta para hacer esto\n"
#: g10/keyedit.c:638 #: g10/keyedit.c:638

View File

@ -1959,7 +1959,7 @@ msgid "Command> "
msgstr "Commande> " msgstr "Commande> "
#: g10/keyedit.c:617 #: g10/keyedit.c:617
msgid "Need the secret key to to this.\n" msgid "Need the secret key to do this.\n"
msgstr "Il faut la clé secrète pour faire cela.\n" msgstr "Il faut la clé secrète pour faire cela.\n"
#: g10/keyedit.c:638 #: g10/keyedit.c:638

View File

@ -1939,7 +1939,7 @@ msgid "Command> "
msgstr "Comando> " msgstr "Comando> "
#: g10/keyedit.c:617 #: g10/keyedit.c:617
msgid "Need the secret key to to this.\n" msgid "Need the secret key to do this.\n"
msgstr "Per fare questo serve la chiave segreta.\n" msgstr "Per fare questo serve la chiave segreta.\n"
#: g10/keyedit.c:638 #: g10/keyedit.c:638

View File

@ -1988,7 +1988,7 @@ msgstr "
#: g10/keyedit.c:617 #: g10/keyedit.c:617
#, fuzzy #, fuzzy
msgid "Need the secret key to to this.\n" msgid "Need the secret key to do this.\n"
msgstr "Чтобы это сделать, нужен секретный ключ.\n" msgstr "Чтобы это сделать, нужен секретный ключ.\n"
#: g10/keyedit.c:638 #: g10/keyedit.c:638

View File

@ -96,6 +96,10 @@ asctimestamp( u32 stamp )
tp = localtime( &atime ); tp = localtime( &atime );
#ifdef HAVE_STRFTIME #ifdef HAVE_STRFTIME
/* fixme: we should check whether the locale apppends a " %Z"
* These locales from glibc don't put the " %Z":
* fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN
*/
strftime( buffer, DIM(buffer)-1, "%c %Z", tp ); strftime( buffer, DIM(buffer)-1, "%c %Z", tp );
buffer[DIM(buffer)-1] = 0; buffer[DIM(buffer)-1] = 0;
#else #else