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
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
-----------------------------------

View File

@ -25,3 +25,5 @@
Can "--dump-options" be used for this or should we place the
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
code. Here is a list of those people. Help me keep it complete and free of
errors.
@ -24,6 +24,7 @@ Frank Heckenbach heckenb@mi.uni-erlangen.de
Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org
Hugh Daniel hugh@toad.com

6
TODO
View File

@ -5,7 +5,7 @@
* 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
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
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 binaries are a.out, so every symbol begins with "_"

View File

@ -300,3 +300,4 @@ zlib/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
record of the DB and the only one with type 1.
1 byte value 2
1 byte value 1
3 bytes 'gpg' magic value
1 byte Version of the TrustDB
1 byte Version of the TrustDB (2)
1 byte marginals needed
1 byte completes needed
1 byte max_cert_depth

View File

@ -1,6 +1,6 @@
=head1 NAME
gpg - GNU Privacy Guard
gpg, gpgm - GNU Privacy Guard
=head1 SYNOPSIS
@ -10,7 +10,7 @@ B<gpgm> [--homedir name] [--options file] [options] command [args]
=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
it does not handle sensitive data and therefore has no need to allocate
secure memory.
@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
B<-kvc> List fingerprints
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
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
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
too.
@ -129,7 +129,7 @@ B<--edit-key> I<name>
B<delkey>
Remove a subkey.
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.
With no selection the key expiration of the
primary key is changed.
@ -190,7 +190,7 @@ B<--export-secret-keys> [I<names>
This is normally not very useful.
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
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>);
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
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
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>
Use I<name> as the user-id for encryption.
This option is silently ignored for the list commands,
@ -252,7 +265,7 @@ B<-t>, B<--textmode>
B<--textmode>) is used together with armoring
and signing, this enables clearsigned messages.
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.
B<-n>, B<--dry-run>
@ -471,16 +484,16 @@ a signature was bad and other errorcode for fatal errors.
=head1 EXAMPLES
-se -r Bob [file] sign and encrypt for user Bob
-sat [file] make a clear text signature
-sb [file] make a detached signature
-k [userid] show keys
-kc [userid] show fingerprint
-se -r Bob [file] sign and encrypt for user Bob
-sat [file] make a clear text signature
-sb [file] make a detached signature
-k [userid] show keys
-kc [userid] show fingerprint
=head1 ENVIRONMENT
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
@ -493,13 +506,13 @@ F<~/.gnupg/pubring.gpg.lock> and the lock file
F<~/.gnupg/trustdb.gpg> The trust database
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
=head1 SEE ALSO
gpg(1) gpgm(1)
gpg(1) gpgm(1)
=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>
* 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
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;
}
/****************
* 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.
*/

View File

@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#define MAINTAINER_OPTIONS
@ -107,6 +108,7 @@ enum cmd_and_opt_values { aNull = 0,
oKeyring,
oSecretKeyring,
oDefaultKey,
oTrustedKey,
oOptions,
oDebug,
oDebugAll,
@ -224,7 +226,7 @@ static ARGPARSE_OPTS opts[] = {
{ oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")},
{ oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
{ 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")},
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
@ -234,6 +236,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
{ 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")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
{ 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 oTrustDBName: trustdb_name = 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 oHomedir: opt.homedir = pargs.r.ret_str; 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"));
}
{ 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) )
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 */
if( i==33 )
s++;
memset(fprint+16, 4, 0);
for(j=0; j < 16; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
if( fprint ) {
memset(fprint+16, 4, 0);
for(j=0; j < 16; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
}
}
mode = 16;
}
else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/
if( i==33 )
s++;
for(j=0; j < 20; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
if( fprint ) {
for(j=0; j < 20; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
return 0;
fprint[j] = c;
}
}
mode = 20;
}
@ -693,6 +697,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
PKT_signature *sig;
KBNODE k;
u32 kid[2];
u32 sigdate = 0;
assert( knode->pkt->pkttype == PKT_PUBLIC_KEY
|| knode->pkt->pkttype == PKT_PUBLIC_SUBKEY );
@ -709,6 +714,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode )
}
else
keyid_from_pk( pk, kid );
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SIGNATURE
&& (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[1] == kid[1]
&& 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
* but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
u32 ed;
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 */
break;
}
}
}
@ -742,6 +754,7 @@ merge_keys_and_selfsig( KBNODE keyblock )
PKT_signature *sig;
KBNODE k;
u32 kid[2] = { 0, 0 };
u32 sigdate = 0;
for(k=keyblock; k; k = k->next ) {
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->sig_class <= 0x30 && sig->version > 3
&& 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
* but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
if( pk ) {
pk->expiredate = p? pk->timestamp + buffer_to_u32(p):0;
/* fixme: add usage etc. */
pk = NULL; /* use only the first self signature */
ed = p? pk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
pk->expiredate = ed;
sigdate = sig->timestamp;
}
}
else {
sk->expiredate = p? sk->timestamp + buffer_to_u32(p):0;
sk = NULL; /* use only the first self signature */
ed = p? sk->timestamp + buffer_to_u32(p):0;
if( sig->timestamp > sigdate ) {
sk->expiredate = ed;
sigdate = sig->timestamp;
}
}
}
}

View File

@ -1,14 +1,14 @@
/* import.c
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNUPG is distributed in the hope that it will be useful,
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@ -64,8 +64,12 @@ static int merge_blocks( const char *fname, KBNODE keyblock_orig,
int *n_uids, int *n_sigs, int *n_subk );
static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
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,
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 |= 1; /* mark that user-id checked */
unode->flag |= 1; /* mark that signature checked */
}
}
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
* 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
* the signature's public key yet; verification is done when putting it
* 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);
insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1;
node->flag |= 1;
log_info_f(fname, _("key %08lX: revocation certificate added\n"),
(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 ) {
if( !(onode->flag & 1) && onode->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
if( node->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
break;
@ -826,15 +826,14 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
/* 3rd: add new user-ids */
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 */
for(onode=keyblock_orig->next; onode; onode=onode->next )
if( !(onode->flag & 1)
&& onode->pkt->pkttype == PKT_USER_ID
&& cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
if( onode->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) )
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);
if( rc )
return rc;
@ -843,8 +842,62 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
}
}
/* 4th: add new subkeys */
/* FIXME */
/* merge subkey certifcates */
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;
}
@ -858,25 +911,43 @@ static int
append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
const char *fname, u32 *keyid )
{
KBNODE n;
KBNODE n, n_where=NULL;
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_f(fname, _("key %08lX: our copy has no self-signature\n"),
(ulong)keyid[1]);
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
* one is released first */
n = clone_kbnode(node);
add_kbnode( keyblock, n );
node->flag |= 1;
if( n_where ) {
insert_kbnode( n_where, n, 0 );
n_where = n;
}
else
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;
@ -909,33 +980,113 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
if( n->pkt->pkttype != PKT_SIGNATURE )
continue;
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
&& 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;
== 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 ) { /* we already have this signature */
/* Hmmm: should we compare the timestamp etc?
* but then we have first to see whether this signature is valid
* - or simply add it in such a case and let trustdb logic
* decide whether to remove the old one
*/
continue;
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;
}
/* 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_SIGNATURE );
n2->flag |= 1;
n->flag |= 1;
++*n_sigs;
}
return 0;
}
/****************
* Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
*/
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;

View File

@ -614,7 +614,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands )
if( !stricmp( answer, cmds[i].name ) )
break;
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;
}
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_signature *copy_signature( PKT_signature *d, PKT_signature *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_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
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 ) {
randomize_buffer(s2k->salt, 8, 1);
if( s2k->mode == 3 )
s2k->count = 96; /* = 56536 */
s2k->count = 96; /* 65536 iterations */
}
if( s2k->mode == 3 ) {

View File

@ -46,6 +46,11 @@
#error Must change structure of trustdb
#endif
struct keyid_list {
struct keyid_list *next;
u32 keyid[2];
};
struct local_id_item {
struct local_id_item *next;
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 *urec, const byte *uidhash, int revoke );
static struct keyid_list *trusted_key_list;
/* 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;
/* 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
verify_own_keys()
@ -449,8 +477,48 @@ verify_own_keys()
PKT_secret_key *sk = m_alloc_clear( sizeof *sk );
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
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 ) ) ) {
int have_pk = 0;
keyid_from_sk( sk, keyid );
if( DBG_TRUST )
@ -460,6 +528,11 @@ verify_own_keys()
log_info(_("NOTE: secret key %08lX is NOT protected.\n"),
(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 */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
@ -468,6 +541,7 @@ verify_own_keys()
(ulong)keyid[1] );
goto skip;
}
have_pk=1;
if( cmp_public_secret_key( pk, sk ) ) {
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",
(ulong)keyid[1], pk->local_id );
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]);
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]);
skip:
release_secret_key_parts( sk );
release_public_key_parts( pk );
if( have_pk )
release_public_key_parts( pk );
}
if( rc != -1 )
log_error(_("enumerate secret keys failed: %s\n"), g10_errstr(rc) );
else
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 */
free_secret_key( sk );
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
* 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
* -1 = not found
* other = error
@ -2282,6 +2366,9 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
urec.r.uid.uidflags |= UIDF_CHECKED | UIDF_VALID;
if( !selfsig )
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 {
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 */
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 )
log_info( "uid %08lX.%lu/%02X%02X: %s\n",
(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;
}
else if( rc == G10ERR_NO_PUBKEY ) {
#if 0 /* fixme: For some reason this really happens? */
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1],
_("Hmmm, public key lost?") );
#endif
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
if( revoke )
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 */
rc = update_trust_record( keyblock, 0, NULL );
rc = update_trust_record( keyblock, 1, NULL );
if( !rc )
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 export_ownertrust(void);
void import_ownertrust(const char *fname);
void register_trusted_key( const char *string );
void check_trustdb( const char *username );
void update_trustdb( void );
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)
* 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 signed long int mpi_limb_signed_t;
typedef struct mpi_struct {
struct gcry_mpi {
int alloced; /* array size (# of allocated limbs) */
int nlimbs; /* number of valid limbs */
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 2: the limb is a pointer to some m_alloced data */
mpi_limb_t *d; /* array with the limbs */
} *MPI;
};
typedef struct gcry_mpi *MPI;
#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>
* config.links: Support for ppc with ELF

View File

@ -124,6 +124,12 @@ case "${target}" in
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])
mpi_sflags="-Wa,-mpwr"
path="power"
@ -146,12 +152,6 @@ case "${target}" in
mpi_sflags="-Wa,-mppc"
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

View File

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

View File

@ -48,7 +48,7 @@ mpihelp_add_n:
mtctr 6 # copy size into CTR
lwz 8,0(4) # load least significant s1 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
bdz Lend # If done, skip loop
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
alignment... */
EALIGN(_mpihelp_add_n,3,0)
EALIGN(mpihelp_add_n,3,0)
/* Set up for loop below. */
mtcrf 0x01,%r6
srwi. %r7,%r6,1
@ -131,6 +131,6 @@ EALIGN(_mpihelp_add_n,3,0)
/* Return the carry. */
1: addze %r3,%r10
blr
END(_mpihelp_add_n)
END(mpihelp_add_n)
#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,
unsigned int cnt) */
EALIGN(_mpihelp_lshift,3,0)
EALIGN(mpihelp_lshift,3,0)
mtctr %r5 # copy size into CTR
cmplwi %cr0,%r5,16 # is size < 16
slwi %r0,%r5,2
@ -194,5 +194,5 @@ L(end2):slw %r0,%r10,%r6
DO_LSHIFT(30)
DO_LSHIFT(31)
END(_mpihelp_lshift)
END(mpihelp_lshift)
#endif

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@ mpihelp_sub_n:
mtctr 6 # copy size into CTR
lwz 8,0(4) # load least significant s1 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
bdz Lend # If done, skip loop
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
alignment... */
EALIGN(_mpihelp_sub_n,3,1)
EALIGN(mpihelp_sub_n,3,1)
/* Set up for loop below. */
mtcrf 0x01,%r6
srwi. %r7,%r6,1
@ -128,5 +128,5 @@ EALIGN(_mpihelp_sub_n,3,1)
1: subfe %r3,%r3,%r3
neg %r3,%r3
blr
END(_mpihelp_sub_n)
END(mpihelp_sub_n)
#endif

View File

@ -44,11 +44,11 @@
/* No profiling of gmp's assembly for now... */
#define CALL_MCOUNT /* no profiling */
#define ENTRY(name) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(2); \
C_LABEL(name) \
#define ENTRY(name) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(2); \
C_LABEL(name) \
CALL_MCOUNT
#define EALIGN_W_0 /* No words to insert. */
@ -62,14 +62,14 @@
/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
past a 2^align boundary. */
#define EALIGN(name, alignt, words) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(alignt); \
EALIGN_W_##words; \
#define EALIGN(name, alignt, words) \
ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
.align ALIGNARG(alignt); \
EALIGN_W_##words; \
C_LABEL(name)
#undef END
#define END(name) \
#define END(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"
#: cipher/rand-dummy.c:112
#,
#,
msgid "WARNING: using insecure random number generator!!\n"
msgstr "Der Zufallszahlengenerator erzeugt keine echten Zufallszahlen!\n"
@ -257,12 +257,12 @@ msgstr ""
" "
#: g10/g10.c:158
#,
#,
msgid "|[file]|make a signature"
msgstr "|[file]|Eine Unterschrift erzeugen"
#: g10/g10.c:159
#,
#,
msgid "|[file]|make a clear text signature"
msgstr "|[file]|Eine Klartextunterschrift erzeugen"
@ -808,7 +808,7 @@ msgid ""
msgstr ""
"Bitte entscheiden Sie, in wieweit Sie diesem User zutrauen,\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"
"\n"
" 1 = Weiß nicht so recht\n"
@ -1964,7 +1964,7 @@ msgid "Command> "
msgstr "Befehl> "
#: 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"
#: g10/keyedit.c:638
@ -2731,7 +2731,7 @@ msgid "lid %lu: insert failed: %s\n"
msgstr "lid %lu: Einfügen fehlgeschlagen: %s\n"
#: g10/trustdb.c:1391
#, c-format
#, c-format
msgid "lid %lu: inserted\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 "
"signatures!\n"
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"
#: g10/status.c:246

View File

@ -1951,7 +1951,7 @@ msgid "Command> "
msgstr "Comando> "
#: 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"
#: g10/keyedit.c:638

View File

@ -1959,7 +1959,7 @@ msgid "Command> "
msgstr "Commande> "
#: 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"
#: g10/keyedit.c:638

View File

@ -1939,7 +1939,7 @@ msgid "Command> "
msgstr "Comando> "
#: 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"
#: g10/keyedit.c:638

View File

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

View File

@ -96,6 +96,10 @@ asctimestamp( u32 stamp )
tp = localtime( &atime );
#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 );
buffer[DIM(buffer)-1] = 0;
#else