some cleanups

This commit is contained in:
Werner Koch 1998-03-19 15:27:29 +00:00
parent 98211af4a7
commit 6b91e7762c
49 changed files with 1737 additions and 452 deletions

8
NEWS
View File

@ -1,3 +1,11 @@
Noteworthy changes in version 0.2.13
------------------------------------
* Verify of DSA signatures works.
* Re-implemented the slower random number generator.
Noteworthy changes in version 0.2.12
------------------------------------

1
THANKS
View File

@ -12,6 +12,7 @@ Hendrik Buschkamp buschkamp@rheumanet.org
James Troup J.J.Troup@scm.brad.ac.uk
Jean-loup Gailly gzip@prep.ai.mit.edu
Jens Bachem bachem@rrz.uni-koeln.de
Marco d'Itri md@linux.it
Mark Adler madler@alumni.caltech.edu
Martin Schulte schulte@thp.uni-koeln.de
Peter Gutmann pgut001@cs.auckland.ac.nz

14
TODO
View File

@ -6,12 +6,12 @@
function of iobuf.
* add checking of armor trailers
* remove all "Fixmes"
* speed up the RIPE-MD-160
* add signal handling
* enable a SIGSEGV handler while using zlib functions
* complete cipher/cast.c
* complete cipher/dsa.c
* complete cipher/cast.c -- have to use the PGP CFBug
* key generation for dsa and subpacket support.
* Burn the buffers used by fopen(), or use read(2).
@ -34,9 +34,11 @@
* add an option to re-create a public key from a secret key
* should we have a simple menu for all the key management options?
* cleanup mainproc.c, much stuff is duplicated.
* remove key management stuff from sign.c.
* add fingerprint/keyid hashing. We need a new filed in PKC to
flag that we may have a cached signature for this (and use the address
of PKC to lookup the hash).

View File

@ -1 +1 @@
0.2.12a
0.2.13a

View File

@ -17,7 +17,8 @@ CLEANFILES = prepared.stamp x y z out err $(DATA_FILES)
check: prepared.stamp
prepared.stamp: pubring.gpg secring.gpg gnupg.sig plain-3 $(DATA_FILES)
prepared.stamp: pubring.gpg secring.gpg gnupg.sig plain-3 \
pubring.pkr secring.skr $(DATA_FILES)
@set -x; \
echo "def" | ../g10/gpg -v --no-operation; \
echo timestamp >./prepared.stamp
@ -30,6 +31,10 @@ gnupg.sig: gnupg.asc
../g10/gpgm --yes --dearmor -o gnupg.sig gnupg.asc
plain-3: plain-3o.asc
../g10/gpgm --yes --dearmor -o plain-3 plain-3o.asc
pubring.pkr: pubring.pkr.asc
../g10/gpgm --yes --dearmor -o pubring.pkr pubring.pkr.asc
secring.skr: secring.skr.asc
../g10/gpgm --yes --dearmor -o secring.skr secring.skr.asc
data-500:
head -c 500 /dev/urandom >data-500

View File

@ -4,7 +4,7 @@
#info Checking decryption of supplied files
for i in $plain_files ; do
echo "$usrpass1" | run_gpg --passphrase-fd 0 -o y --yes $i.asc
echo "$usrpass1" | run_gpg --passphrase-fd 0 -o y --yes $i.asc
cmp $i y || error "$i: mismatch"
done

View File

@ -1,3 +1,35 @@
Thu Mar 19 13:54:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* blowfish.c (blowfish_decode_cfb): changed XOR operation
(blowfish_encode_cfb): Ditto.
Thu Mar 12 14:04:05 1998 Werner Koch (wk@isil.d.shuttle.de)
* sha1.c (transform): Rewrote
* blowfish.c (encrypt): Unrolled for rounds == 16
(decrypt): Ditto.
Tue Mar 10 16:32:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* rmd160.c (transform): Unrolled the loop.
Tue Mar 10 13:05:14 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (read_pool): Add pool_balance stuff.
(get_random_bits): New.
* elgamal.c (elg_generate): Now uses get_random_bits to generate x.
Tue Mar 10 11:33:51 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_digest_length): New.
Tue Mar 10 11:27:41 1998 Werner Koch (wk@isil.d.shuttle.de)
* dsa.c (dsa_verify): Works.
Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* dsa.c, dsa.h: Removed some unused code.

View File

@ -227,8 +227,7 @@ static const u32 ps[BLOWFISH_ROUNDS+2] = {
#if BLOWFISH_ROUNDS != 16
static inline u32
function_F( BLOWFISH_context *bc, u32 x )
{
@ -248,48 +247,130 @@ function_F( BLOWFISH_context *bc, u32 x )
return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
}
#endif
#ifdef BIG_ENDIAN_HOST
#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
#else
#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
#endif
#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
static void
encrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
u32 xl, xr, temp;
#if BLOWFISH_ROUNDS == 16
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
s0 = bc->s0;
s1 = bc->s1;
s2 = bc->s2;
s3 = bc->s3;
R( xl, xr, 0);
R( xr, xl, 1);
R( xl, xr, 2);
R( xr, xl, 3);
R( xl, xr, 4);
R( xr, xl, 5);
R( xl, xr, 6);
R( xr, xl, 7);
R( xl, xr, 8);
R( xr, xl, 9);
R( xl, xr, 10);
R( xr, xl, 11);
R( xl, xr, 12);
R( xr, xl, 13);
R( xl, xr, 14);
R( xr, xl, 15);
xl ^= p[BLOWFISH_ROUNDS];
xr ^= p[BLOWFISH_ROUNDS+1];
*ret_xl = xr;
*ret_xr = xl;
#else
u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for(i=0; i < BLOWFISH_ROUNDS; i++ ) {
xl ^= bc->p[i];
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
temp = xl;
xl = xr;
xr = temp;
xr ^= bc->p[BLOWFISH_ROUNDS];
xl ^= bc->p[BLOWFISH_ROUNDS+1];
xr ^= p[BLOWFISH_ROUNDS];
xl ^= p[BLOWFISH_ROUNDS+1];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
static void
decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
u32 xl, xr, temp;
#if BLOWFISH_ROUNDS == 16
u32 xl, xr, *s0, *s1, *s2, *s3, *p;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
s0 = bc->s0;
s1 = bc->s1;
s2 = bc->s2;
s3 = bc->s3;
R( xl, xr, 17);
R( xr, xl, 16);
R( xl, xr, 15);
R( xr, xl, 14);
R( xl, xr, 13);
R( xr, xl, 12);
R( xl, xr, 11);
R( xr, xl, 10);
R( xl, xr, 9);
R( xr, xl, 8);
R( xl, xr, 7);
R( xr, xl, 6);
R( xl, xr, 5);
R( xr, xl, 4);
R( xl, xr, 3);
R( xr, xl, 2);
xl ^= p[1];
xr ^= p[0];
*ret_xl = xr;
*ret_xr = xl;
#else
u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
p = bc->p;
for(i=BLOWFISH_ROUNDS+1; i > 1; i-- ) {
xl ^= bc->p[i];
xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
@ -300,13 +381,17 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
xl = xr;
xr = temp;
xr ^= bc->p[1];
xl ^= bc->p[0];
xr ^= p[1];
xl ^= p[0];
*ret_xl = xl;
*ret_xr = xr;
#endif
}
#undef F
#undef R
static void
encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{
@ -539,6 +624,7 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf,
byte *inbuf, unsigned nbytes)
{
unsigned n;
int is_aligned;
if( c->count ) { /* must make a full block first */
assert( c->count < BLOWFISH_BLOCKSIZE );
@ -560,8 +646,26 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf,
return;
}
assert(!c->count);
is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
if( is_aligned ) {
#if SIZEOF_UNSIGNED_LONG == BLOWFISH_BLOCKSIZE
*(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf;
#elif (2*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
#elif (4*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2];
((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3];
#else
#error Please remove this info line.
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
#endif
}
else /* not aligned */
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE);
encrypt_block( c, c->eniv, c->iv );
nbytes -= BLOWFISH_BLOCKSIZE;
@ -583,6 +687,7 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
byte *inbuf, unsigned nbytes)
{
unsigned n;
int is_aligned;
if( c->count ) { /* must make a full block first */
assert( c->count < BLOWFISH_BLOCKSIZE );
@ -605,9 +710,27 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
}
assert(!c->count);
is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE);
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
if( is_aligned ) {
#if SIZEOF_UNSIGNED_LONG == BLOWFISH_BLOCKSIZE
*(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf;
#elif (2*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
#elif (4*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2];
((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3];
#else
#error Please remove this info line.
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
#endif
}
else /* not aligned */
xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE);
encrypt_block( c, c->eniv, c->iv );
nbytes -= BLOWFISH_BLOCKSIZE;
inbuf += BLOWFISH_BLOCKSIZE;
@ -622,3 +745,4 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
}

View File

@ -27,6 +27,32 @@
#include "cipher.h"
#include "dsa.h"
/****************
* Generate a random secret exponent k less than q
*/
static MPI
gen_k( MPI q )
{
MPI k = mpi_alloc_secure( mpi_get_nlimbs(q) );
unsigned nbits = mpi_get_nbits(q);
if( DBG_CIPHER )
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( k, nbits , get_random_byte, 1 );
if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
continue; /* no */
if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
continue; /* no */
break; /* okay */
}
if( DBG_CIPHER )
fputc('\n', stderr);
return k;
}
void
dsa_free_public_key( DSA_public_key *pk )
@ -67,12 +93,36 @@ dsa_check_secret_key( DSA_secret_key *sk )
/****************
* Make a DSA signature out of INPUT
* Make a DSA signature from HASH and put it into r and s.
*/
void
dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey )
dsa_sign(MPI r, MPI s, MPI hash, DSA_secret_key *skey )
{
MPI k;
MPI kinv;
MPI tmp;
/* select a random k with 0 < k < q */
k = gen_k( skey->q );
/* r = (a^k mod p) mod q */
mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q );
/* kinv = k^(-1) mod q */
kinv = mpi_alloc( mpi_get_nlimbs(k) );
mpi_invm(kinv, k, skey->q );
/* s = (kinv * ( hash + x * r)) mod q */
tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
mpi_mul( tmp, skey->x, r );
mpi_add( tmp, tmp, hash );
mpi_mulm( s , kinv, tmp, skey->q );
mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
}
@ -80,7 +130,7 @@ dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey )
* Returns true if the signature composed from R and S is valid.
*/
int
dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey )
dsa_verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey )
{
int rc;
MPI w, u1, u2, v;
@ -100,8 +150,8 @@ dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey )
/* w = s^(-1) mod q */
mpi_invm( w, s, pkey->q );
/* u1 = (input * w) mod q */
mpi_mulm( u1, input, w, pkey->q );
/* u1 = (hash * w) mod q */
mpi_mulm( u1, hash, w, pkey->q );
/* u2 = r * w mod q */
mpi_mulm( u2, r, w, pkey->q );

View File

@ -152,9 +152,14 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk,
if( DBG_CIPHER )
log_debug("choosing a random x ");
do {
byte *rndbuf;
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( x, nbits, get_random_byte, 2 );
rndbuf = get_random_bits( nbits, 2, 1 );
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
m_free(rndbuf);
mpi_clear_highbit( x, nbits+1 );
log_mpidump(" x: ", x );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);

View File

@ -170,6 +170,21 @@ md_get_algo( MD_HANDLE a )
return 0;
}
/****************
* Return the length of the digest
*/
int
md_digest_length( int algo )
{
switch( algo ) {
case DIGEST_ALGO_RMD160:
case DIGEST_ALGO_SHA1:
return 20;
default:
return 16;
}
}
const byte *
md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )

View File

@ -58,6 +58,7 @@ void md_write( MD_HANDLE a, byte *inbuf, size_t inlen);
void md_final(MD_HANDLE a);
byte *md_read( MD_HANDLE a, int algo );
int md_get_algo( MD_HANDLE a );
int md_digest_length( int algo );
const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
#define md_is_secure(a) ((a)->secure)

View File

@ -89,6 +89,7 @@ static char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */
static size_t pool_readpos;
static size_t pool_writepos;
static int pool_filled;
static int pool_balance;
static int just_mixed;
static int secure_alloc;
@ -166,6 +167,26 @@ get_random_byte( int level )
}
/****************
* Return a pointer to a randomized buffer of level 0 and LENGTH bits
* caller must free the buffer. This function does not use the
* cache (will be removed in future). Note: The returned value is
* rounded up to bytes.
*/
byte *
get_random_bits( size_t nbits, int level, int secure )
{
byte *buf;
size_t nbytes = (nbits+7)/8;
MASK_LEVEL(level);
buf = secure? m_alloc_secure( nbytes ) : m_alloc( nbytes );
read_pool( buf, nbytes, level );
return buf;
}
/****************
* Mix the pool
*/
@ -223,9 +244,23 @@ read_pool( byte *buffer, size_t length, int level )
return;
}
/* always do a random poll if we need strong numbers */
if( pool_filled && level == 2 )
random_poll();
/* for level 2 make sure that there is enough random in the pool */
if( level == 2 && pool_balance < length ) {
size_t needed;
byte *p;
if( pool_balance < 0 )
pool_balance = 0;
needed = length - pool_balance;
if( needed > POOLSIZE )
BUG();
p = m_alloc_secure( needed );
read_dev_random( p, needed, 2 ); /* read /dev/random */
add_randomness( p, needed, 3);
m_free(p);
pool_balance += needed;
}
/* make sure the pool is filled */
while( !pool_filled )
random_poll();
@ -250,7 +285,10 @@ read_pool( byte *buffer, size_t length, int level )
*buffer++ = keypool[pool_readpos++];
if( pool_readpos >= POOLSIZE )
pool_readpos = 0;
pool_balance--;
}
if( pool_balance < 0 )
pool_balance = 0;
/* and clear the keypool */
memset( keypool, 0, POOLSIZE );
}

View File

@ -27,6 +27,7 @@ void secure_random_alloc(void);
int quick_random_gen( int onoff );
void randomize_buffer( byte *buffer, size_t length, int level );
byte get_random_byte( int level );
byte *get_random_bits( size_t nbits, int level, int secure );
void add_randomness( const void *buffer, size_t length, int source );

View File

@ -61,6 +61,9 @@
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
@ -76,6 +79,9 @@
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if `sys_siglist' is declared by <signal.h>. */
#undef SYS_SIGLIST_DECLARED
#undef M_DEBUG
#undef M_GUARD
#undef VERSION

View File

@ -21,7 +21,7 @@ fi
VERSION=`cat $srcdir/VERSION`
PACKAGE=gnupg
ALL_LINGUAS="de"
ALL_LINGUAS="de it"
AC_SUBST(VERSION)
AC_SUBST(PACKAGE)
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
@ -108,6 +108,8 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_TYPE_SIGNAL
AC_DECL_SYS_SIGLIST
WK_CHECK_ENDIAN

View File

@ -1,3 +1,38 @@
Thu Mar 19 15:22:36 1998 Werner Koch (wk@isil.d.shuttle.de)
* ringedit.c (keyring_enum): Fixed problem with reading too
many packets. Add support to read secret keyrings.
* getkey.c (scan_keyring): Removed
(lookup): New to replace scan_keyring.
(scan_secret_keyring): Removed.
(lookup_skc): New.
Wed Mar 18 11:47:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* ringedit.c (enum_keyblocks): New read mode 11.
* keyid.c (elg_fingerprint_md): New and changed all other functions
to call this if the packet version is 4 or above.
Tue Mar 17 20:46:16 1998 Werner Koch (wk@isil.d.shuttle.de)
* parse-packet.c (parse_certificate): Add listing support for subkeys.
Tue Mar 17 20:32:22 1998 Werner Koch (wk@isil.d.shuttle.de)
* armor.c (is_armored): Allow marker packet.
Thu Mar 12 13:36:49 1998 Werner Koch (wk@isil.d.shuttle.de)
* trustdb.c (check_trust): Checks timestamp of pubkey.
* sig-check. (do_check): Compares timestamps.
Tue Mar 10 17:01:56 1998 Werner Koch (wk@isil.d.shuttle.de)
* g10.c (main): Add call to init_signals.
* signal.c: New.
Mon Mar 9 12:43:42 1998 Werner Koch (wk@isil.d.shuttle.de)
* dsa.c: New

View File

@ -50,7 +50,8 @@ common_source = \
encode.c \
revoke.c \
keylist.c \
sig-check.c
sig-check.c \
signal.c
gpg_SOURCES = g10.c \
$(common_source) \

View File

@ -142,7 +142,8 @@ common_source = \
encode.c \
revoke.c \
keylist.c \
sig-check.c
sig-check.c \
signal.c
gpg_SOURCES = g10.c \
$(common_source) \
@ -170,7 +171,8 @@ pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \
textfilter.o cipher.o elg.o dsa.o rsa.o openfile.o keyid.o trustdb.o \
parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o seskey.o \
import.o export.o comment.o status.o sign.o plaintext.o encr-data.o \
encode.o revoke.o keylist.o sig-check.o verify.o decrypt.o keygen.o
encode.o revoke.o keylist.o sig-check.o signal.o verify.o decrypt.o \
keygen.o
gpg_LDADD = $(LDADD)
gpg_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
../util/libutil.a
@ -180,7 +182,8 @@ free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o \
mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o dsa.o rsa.o \
openfile.o keyid.o trustdb.o parse-packet.o passphrase.o pubkey-enc.o \
seckey-cert.o seskey.o import.o export.o comment.o status.o sign.o \
plaintext.o encr-data.o encode.o revoke.o keylist.o sig-check.o
plaintext.o encr-data.o encode.o revoke.o keylist.o sig-check.o \
signal.o
gpgm_LDADD = $(LDADD)
gpgm_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
../util/libutil.a
@ -204,8 +207,8 @@ DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \
.deps/openfile.P .deps/parse-packet.P .deps/passphrase.P \
.deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P .deps/revoke.P \
.deps/ringedit.P .deps/rsa.P .deps/seckey-cert.P .deps/seskey.P \
.deps/sig-check.P .deps/sign.P .deps/skclist.P .deps/status.P \
.deps/textfilter.P .deps/trustdb.P .deps/verify.P
.deps/sig-check.P .deps/sign.P .deps/signal.P .deps/skclist.P \
.deps/status.P .deps/textfilter.P .deps/trustdb.P .deps/verify.P
SOURCES = $(gpg_SOURCES) $(gpgm_SOURCES)
OBJECTS = $(gpg_OBJECTS) $(gpgm_OBJECTS)

View File

@ -150,6 +150,7 @@ is_armored( byte *buf )
return 1; /* invalid packet: assume it is armored */
pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
switch( pkttype ) {
case PKT_MARKER:
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
case PKT_PUBKEY_ENC:

View File

@ -47,10 +47,10 @@ cipher_filter( void *opaque, int control,
cipher_filter_context_t *cfx = opaque;
int rc=0;
if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypted */
if( control == IOBUFCTRL_UNDERFLOW ) { /* decrypt */
rc = -1; /* FIXME:*/
}
else if( control == IOBUFCTRL_FLUSH ) { /* encrypted */
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
assert(a);
if( !cfx->header ) {
PACKET pkt;

View File

@ -54,7 +54,10 @@ g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
sig->digest_start[1] = dp[1];
sig->d.dsa.r = mpi_alloc( mpi_get_nlimbs(skc->d.dsa.p) );
sig->d.dsa.s = mpi_alloc( mpi_get_nlimbs(skc->d.dsa.p) );
frame = encode_md_value( md, mpi_get_nbits(skc->d.dsa.p));
frame = mpi_alloc( (md_digest_length(digest_algo)+BYTES_PER_MPI_LIMB-1)
/ BYTES_PER_MPI_LIMB );
mpi_set_buffer( frame, md_read(md, digest_algo),
md_digest_length(digest_algo), 0 );
skey.p = skc->d.elg.p;
skey.g = skc->d.elg.g;
skey.y = skc->d.elg.y;

View File

@ -31,6 +31,7 @@
#include <string.h>
#include <unistd.h>
#include "packet.h"
#include "iobuf.h"
#include "memory.h"
@ -99,7 +100,7 @@ static ARGPARSE_OPTS opts[] = {
#endif
{ 'o', "output", 2, N_("use as output file")},
{ 'v', "verbose", 0, N_("verbose") },
{ 'n', "dry-run", 0, N_("don't make any changes") },
{ 'n', "dry-run", 0, N_("do not make any changes") },
{ 500, "batch", 0, N_("batch mode: never ask")},
{ 501, "yes", 0, N_("assume yes on most questions")},
{ 502, "no", 0, N_("assume no on most questions")},
@ -275,7 +276,7 @@ build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
static void
i18n_init(void)
{
#ifdef HAVE_LIBINTL
#ifdef ENABLE_NLS
#ifdef HAVE_LC_MESSAGES
setlocale( LC_MESSAGES, "" );
#else
@ -393,6 +394,7 @@ main( int argc, char **argv )
*/
log_set_name("gpg");
secure_random_alloc(); /* put random number into secure memory */
init_signals();
#endif
i18n_init();
opt.compress = -1; /* defaults to standard compress level */

View File

@ -68,10 +68,10 @@ static pkc_cache_entry_t pkc_cache;
static int pkc_cache_entries; /* number of entries in pkc cache */
static int scan_keyring( PKT_public_cert *pkc, u32 *keyid,
const char *name, const char *filename );
static int scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
const char *name, const char *filename);
static int lookup( PKT_public_cert *pkc,
int mode, u32 *keyid, const char *name );
static int lookup_skc( PKT_secret_cert *skc,
int mode, u32 *keyid, const char *name );
/* note this function may be called before secure memory is
* available */
@ -161,7 +161,7 @@ add_secret_keyring( const char *name )
}
void
static void
cache_public_cert( PKT_public_cert *pkc )
{
pkc_cache_entry_t ce;
@ -214,7 +214,7 @@ cache_user_id( PKT_user_id *uid, u32 *keyid )
for(r=user_id_db; r; r = r->next )
if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
if( DBG_CACHE )
log_debug("cache_user_id: already in cache\n");
log_debug("cache_user_id: already in cache\n");
return;
}
@ -241,7 +241,6 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
int internal = 0;
int rc = 0;
pkc_cache_entry_t ce;
STRLIST sl;
/* lets see wether we checked the keyid already */
@ -249,14 +248,13 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
return G10ERR_NO_PUBKEY; /* already checked and not found */
/* 1. Try to get it from our cache */
/* Try to get it from our cache */
for( ce = pkc_cache; ce; ce = ce->next )
if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
if( pkc )
copy_public_cert( pkc, ce->pkc );
return 0;
}
/* more init stuff */
if( !pkc ) {
pkc = m_alloc_clear( sizeof *pkc );
@ -264,14 +262,12 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
}
/* 2. Try to get it from the keyrings */
for(sl = keyrings; sl; sl = sl->next )
if( !scan_keyring( pkc, keyid, NULL, sl->d ) )
goto leave;
/* do a lookup */
rc = lookup( pkc, 11, keyid, NULL );
if( !rc )
goto leave;
/* 3. Try to get it from a key server */
/* 4. not found: store it for future reference */
/* not found: store it for future reference */
kl = m_alloc( sizeof *kl );
kl->keyid[0] = keyid[0];
kl->keyid[1] = keyid[1];
@ -288,6 +284,32 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
}
static int
hextobyte( const byte *s )
{
int c;
if( *s >= '0' && *s <= '9' )
c = 16 * (*s - '0');
else if( *s >= 'A' && *s <= 'F' )
c = 16 * (10 + *s - 'A');
else if( *s >= 'a' && *s <= 'f' )
c = 16 * (10 + *s - 'a');
else
return -1;
s++;
if( *s >= '0' && *s <= '9' )
c += *s - '0';
else if( *s >= 'A' && *s <= 'F' )
c += 10 + *s - 'A';
else if( *s >= 'a' && *s <= 'f' )
c += 10 + *s - 'a';
else
return -1;
return c;
}
/****************
* Try to get the pubkey by the userid. This functions looks for the
* first pubkey certificate which has the given name in a user_id.
@ -302,26 +324,30 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
* (Not yet implemented)
* - If the username starts with a left angle, we assume it is a complete
* email address and look only at this part.
* - If the username starts with a '.', we assume it is the ending
* part of an email address
* - If the username starts with an '@', we assume it is a part of an
* email address
* - If the userid start with an '=' an exact compare is done; this may
* also follow the keyid in which case both parts are matched.
* (Not yet implemented)
*
* - If the userid starts with a '*' a case insensitive substring search is
* done (This is also the default).
*/
int
get_pubkey_byname( PKT_public_cert *pkc, const char *name )
{
int internal = 0;
int rc = 0;
STRLIST sl;
const char *s;
u32 keyid[2] = {0}; /* init to avoid compiler warning */
int use_keyid=0;
byte fprint[20];
int mode = 0;
/* check what kind of name it is */
for(s = name; *s && isspace(*s); s++ )
;
if( isdigit( *s ) ) { /* a keyid */
int i;
if( isdigit( *s ) ) { /* a keyid or a fingerprint */
int i, j;
char buf[9];
if( *s == '0' && s[1] == 'x' && isxdigit(s[2]) )
@ -334,7 +360,7 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name )
if( i==9 )
s++;
keyid[1] = strtoul( s, NULL, 16 );
use_keyid++;
mode = 10;
}
else if( i == 16 || (i == 17 && *s == '0') ) { /* complete keyid */
if( i==17 )
@ -342,51 +368,73 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name )
mem2str(buf, s, 9 );
keyid[0] = strtoul( buf, NULL, 16 );
keyid[1] = strtoul( s+8, NULL, 16 );
return get_pubkey( pkc, keyid );
mode = 11;
}
else if( i == 32 || ( i == 33 && *s == '0' ) ) { /* md5 fingerprint */
if( i==33 )
s++;
memset(fprint+16, 4, 0);
for(j=0; !rc && j < 16; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
rc = G10ERR_INV_USER_ID;
else
fprint[j] = c;
}
mode = 16;
}
else if( i == 40 || ( i == 41 && *s == '0' ) ) { /* sha1/rmd160 fprint*/
if( i==33 )
s++;
for(j=0; !rc && j < 20; j++, s+=2 ) {
int c = hextobyte( s );
if( c == -1 )
rc = G10ERR_INV_USER_ID;
else
fprint[j] = c;
}
mode = 20;
}
else
rc = G10ERR_INV_USER_ID;
}
else if( *s == '<' ) { /* an email address */
/* for now handled like a substring */
/* a keyserver might use this for quicker access */
}
else if( *s == '=' ) { /* exact search */
rc = G10ERR_INV_USER_ID; /* nox yet implemented */
}
else if( *s == '#' ) { /* use local id */
rc = G10ERR_INV_USER_ID; /* nox yet implemented */
mode = 1;
s++;
}
else if( *s == '*' ) { /* substring search */
name++;
mode = 2;
s++;
}
else if( *s == '<' ) { /* an email address */
mode = 3;
}
else if( *s == '@' ) { /* a part of an email address */
mode = 4;
s++;
}
else if( *s == '.' ) { /* an email address, compare from end */
mode = 5;
s++;
}
else if( *s == '#' ) { /* use local id */
rc = G10ERR_INV_USER_ID; /* not yet implemented */
}
else if( !*s ) /* empty string */
rc = G10ERR_INV_USER_ID;
else
mode = 2;
if( rc )
goto leave;
if( !pkc ) {
pkc = m_alloc_clear( sizeof *pkc );
internal++;
}
/* 2. Try to get it from the keyrings */
for(sl = keyrings; sl; sl = sl->next )
if( use_keyid ) {
if( !scan_keyring( pkc, keyid, name, sl->d ) )
goto leave;
}
else {
if( !scan_keyring( pkc, NULL, name, sl->d ) )
goto leave;
}
/* 3. Try to get it from a key server */
/* 4. not found: store it for future reference */
rc = G10ERR_NO_PUBKEY;
rc = mode < 16? lookup( pkc, mode, keyid, name )
: lookup( pkc, mode, keyid, fprint );
leave:
if( internal )
@ -401,23 +449,16 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name )
int
get_seckey( PKT_secret_cert *skc, u32 *keyid )
{
STRLIST sl;
int rc=0;
int rc;
for(sl = secret_keyrings; sl; sl = sl->next )
if( !(rc=scan_secret_keyring( skc, keyid, NULL, sl->d )) )
goto found;
/* fixme: look at other places */
goto leave;
rc = lookup_skc( skc, 11, keyid, NULL );
if( !rc ) {
/* check the secret key (this may prompt for a passprase to
* unlock the secret key
*/
rc = check_secret_key( skc );
}
found:
/* get the secret key (this may prompt for a passprase to
* unlock the secret key
*/
if( (rc = check_secret_key( skc )) )
goto leave;
leave:
return rc;
}
@ -430,18 +471,10 @@ int
seckey_available( u32 *keyid )
{
PKT_secret_cert *skc;
STRLIST sl;
int rc=0;
int rc;
skc = m_alloc_clear( sizeof *skc );
for(sl = secret_keyrings; sl; sl = sl->next )
if( !(rc=scan_secret_keyring( skc, keyid, NULL, sl->d )) )
goto found;
/* fixme: look at other places */
goto leave;
found:
leave:
rc = lookup_skc( skc, 11, keyid, NULL );
free_secret_cert( skc );
return rc;
}
@ -455,287 +488,294 @@ seckey_available( u32 *keyid )
int
get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect )
{
STRLIST sl;
int rc=0;
int rc;
for(sl = secret_keyrings; sl; sl = sl->next )
if( !(rc=scan_secret_keyring( skc, NULL, name, sl->d ) ) )
goto found;
/* fixme: look at other places */
goto leave;
/* fixme: add support for compare_name */
rc = lookup_skc( skc, name? 2:15, NULL, name );
if( !rc && unprotect )
rc = check_secret_key( skc );
found:
/* get the secret key (this may prompt for a passprase to
* unlock the secret key
*/
if( unprotect )
if( (rc = check_secret_key( skc )) )
goto leave;
leave:
return rc;
}
/****************
* scan the keyring and look for either the keyid or the name.
* If both, keyid and name are given, look for keyid but use only
* the low word of it (name is only used as a flag to indicate this mode
* of operation).
*/
static int
scan_keyring( PKT_public_cert *pkc, u32 *keyid,
const char *name, const char *filename )
compare_name( const char *uid, size_t uidlen, const char *name, int mode )
{
compress_filter_context_t cfx;
int rc=0;
int found = 0;
IOBUF a;
PACKET pkt;
int save_mode;
u32 akeyid[2];
PKT_public_cert *last_pk = NULL;
int shortkeyid;
int i;
shortkeyid = keyid && name;
if( shortkeyid )
name = NULL; /* not used anymore */
if( !(a = iobuf_open( filename ) ) ) {
log_debug("scan_keyring: can't open '%s'\n", filename );
return G10ERR_KEYRING_OPEN;
if( mode == 1 ) { /* exact match */
for(i=0; name[i] && uidlen; i++, uidlen-- )
if( uid[i] != name[i] )
break;
if( !uidlen && !name[i] )
return 0; /* found */
}
else if( mode == 2 ) { /* case insensitive substring */
if( memistr( uid, uidlen, name ) )
return 0;
}
else if( mode == 3 ) { /* case insensitive email address */
/* FIXME: not yet implemented */
if( memistr( uid, uidlen, name ) )
return 0;
}
else if( mode == 4 ) { /* email substring */
/* FIXME: not yet implemented */
if( memistr( uid, uidlen, name ) )
return 0;
}
else if( mode == 5 ) { /* email from end */
/* FIXME: not yet implemented */
if( memistr( uid, uidlen, name ) )
return 0;
}
if( !DBG_CACHE )
;
else if( shortkeyid )
log_debug("scan_keyring %s for %08lx\n", filename, (ulong)keyid[1] );
else if( name )
log_debug("scan_keyring %s for '%s'\n", filename, name );
else if( keyid )
log_debug("scan_keyring %s for %08lx %08lx\n", filename,
(ulong)keyid[0], (ulong)keyid[1] );
else
log_debug("scan_keyring %s (all)\n", filename );
BUG();
save_mode = set_packet_list_mode(0);
init_packet(&pkt);
while( (rc=parse_packet(a, &pkt)) != -1 ) {
if( rc )
; /* e.g. unknown packet */
else if( keyid && found && pkt.pkttype == PKT_PUBLIC_CERT ) {
log_error("Hmmm, pubkey without an user id in '%s'\n", filename);
goto leave;
}
else if( pkt.pkttype == PKT_COMPRESSED ) {
memset( &cfx, 0, sizeof cfx );
if( pkt.pkt.compressed->algorithm == 1 )
cfx.pgpmode = 1;
else if( pkt.pkt.compressed->algorithm != 2 ){
rc = G10ERR_COMPR_ALGO;
log_error("compressed keyring: %s\n", g10_errstr(rc) );
break;
}
pkt.pkt.compressed->buf = NULL;
iobuf_push_filter( a, compress_filter, &cfx );
}
else if( keyid && pkt.pkttype == PKT_PUBLIC_CERT ) {
switch( pkt.pkt.public_cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_DSA:
case PUBKEY_ALGO_RSA:
keyid_from_pkc( pkt.pkt.public_cert, akeyid );
if( (shortkeyid || akeyid[0] == keyid[0])
&& akeyid[1] == keyid[1] ) {
copy_public_cert( pkc, pkt.pkt.public_cert );
found++;
}
break;
default:
log_error("cannot handle pubkey algo %d\n",
pkt.pkt.public_cert->pubkey_algo);
}
}
else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
cache_user_id( pkt.pkt.user_id, keyid );
goto leave;
}
else if( name && pkt.pkttype == PKT_PUBLIC_CERT ) {
if( last_pk )
free_public_cert(last_pk);
last_pk = pkt.pkt.public_cert;
pkt.pkt.public_cert = NULL;
}
else if( name && pkt.pkttype == PKT_USER_ID ) {
if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
if( !last_pk )
log_error("Ooops: no pubkey for userid '%.*s'\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
else if( pkc->pubkey_algo &&
pkc->pubkey_algo != last_pk->pubkey_algo )
log_info("skipping id '%.*s': want algo %d, found %d\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name,
pkc->pubkey_algo, last_pk->pubkey_algo );
else {
copy_public_cert( pkc, last_pk );
goto leave;
}
}
}
else if( !keyid && !name && pkt.pkttype == PKT_PUBLIC_CERT ) {
if( last_pk )
free_public_cert(last_pk);
last_pk = pkt.pkt.public_cert;
pkt.pkt.public_cert = NULL;
}
else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
if( !last_pk )
log_error("Ooops: no pubkey for userid '%.*s'\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
else {
if( last_pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|| last_pk->pubkey_algo == PUBKEY_ALGO_DSA
|| last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
keyid_from_pkc( last_pk, akeyid );
cache_user_id( pkt.pkt.user_id, akeyid );
}
cache_public_cert( last_pk );
}
}
free_packet(&pkt);
}
rc = G10ERR_NO_PUBKEY;
leave:
if( last_pk )
free_public_cert(last_pk);
free_packet(&pkt);
iobuf_close(a);
set_packet_list_mode(save_mode);
return rc;
return -1; /* not found */
}
/****************
* This is the function to get a secret key. We use an extra function,
* so that we can easily add special handling for secret keyrings
* PKT returns the secret key certificate.
* Lookup a key by scanning all keyrings
* mode 1 = lookup by NAME (exact)
* 2 = lookup by NAME (substring)
* 3 = lookup by NAME (email address)
* 4 = email address (substring)
* 5 = email address (compare from end)
* 10 = lookup by short KEYID (don't care about keyid[0])
* 11 = lookup by long KEYID
* 15 = Get the first key.
* 16 = lookup by 16 byte fingerprint which is stored in NAME
* 20 = lookup by 20 byte fingerprint which is stored in NAME
* Caller must provide an empty PKC, if the pubkey_algo is filled in, only
* a key of this algo will be returned.
*/
static int
scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
const char *name, const char *filename )
lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name )
{
int rc=0;
int found = 0;
IOBUF a;
PACKET pkt;
int save_mode;
u32 akeyid[2];
PKT_secret_cert *last_pk = NULL;
int get_first;
u32 dummy_keyid[2];
int rc;
KBNODE keyblock = NULL;
KBPOS kbpos;
get_first = !keyid && !name;
if( get_first )
keyid = dummy_keyid;
if( !(a = iobuf_open( filename ) ) ) {
log_debug("scan_secret_keyring: can't open '%s'\n", filename );
return G10ERR_KEYRING_OPEN;
rc = enum_keyblocks( 0, &kbpos, &keyblock );
if( rc ) {
if( rc == -1 )
rc = G10ERR_NO_PUBKEY;
else if( rc )
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
goto leave;
}
save_mode = set_packet_list_mode(0);
init_packet(&pkt);
while( (rc=parse_packet(a, &pkt)) != -1 ) {
if( rc )
; /* e.g. unknown packet */
else if( keyid && found && pkt.pkttype == PKT_SECRET_CERT ) {
log_error("Hmmm, seckey without an user id in '%s'\n", filename);
goto leave;
}
else if( keyid && pkt.pkttype == PKT_SECRET_CERT ) {
switch( pkt.pkt.secret_cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL:
case PUBKEY_ALGO_DSA:
case PUBKEY_ALGO_RSA:
if( get_first ) {
copy_secret_cert( skc, pkt.pkt.secret_cert );
found++;
}
else {
keyid_from_skc( pkt.pkt.secret_cert, akeyid );
if( (akeyid[0] == keyid[0] && akeyid[1] == keyid[1]) ) {
copy_secret_cert( skc, pkt.pkt.secret_cert );
found++;
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
KBNODE k, kk;
if( mode < 10 ) { /* name lookup */
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_USER_ID
&& !compare_name( k->pkt->pkt.user_id->name,
k->pkt->pkt.user_id->len, name, mode)) {
/* we found a matching name, look for the key */
for(kk=keyblock; kk; kk = kk->next )
if( ( kk->pkt->pkttype == PKT_PUBLIC_CERT
|| kk->pkt->pkttype == PKT_PUBKEY_SUBCERT )
&& ( !pkc->pubkey_algo
|| pkc->pubkey_algo
== kk->pkt->pkt.public_cert->pubkey_algo))
break;
if( kk ) {
u32 aki[2];
keyid_from_pkc( kk->pkt->pkt.public_cert, aki );
cache_user_id( k->pkt->pkt.user_id, aki );
k = kk;
break;
}
}
break;
default:
log_error("cannot handle pubkey algo %d\n",
pkt.pkt.secret_cert->pubkey_algo);
}
}
else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
goto leave;
}
else if( name && pkt.pkttype == PKT_SECRET_CERT ) {
if( last_pk )
free_secret_cert(last_pk);
last_pk = pkt.pkt.secret_cert;
pkt.pkt.secret_cert = NULL;
}
else if( name && pkt.pkttype == PKT_USER_ID ) {
if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
if( !last_pk )
log_error("Ooops: no seckey for userid '%.*s'\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
else if( skc->pubkey_algo &&
skc->pubkey_algo != last_pk->pubkey_algo )
log_info("skipping id '%.*s': want algo %d, found %d\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name,
skc->pubkey_algo, last_pk->pubkey_algo );
else {
copy_secret_cert( skc, last_pk );
goto leave;
else
log_error("No key for userid\n");
}
}
}
else if( !keyid && !name && pkt.pkttype == PKT_SECRET_CERT ) {
if( last_pk )
free_secret_cert(last_pk);
last_pk = pkt.pkt.secret_cert;
pkt.pkt.secret_cert = NULL;
}
else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
if( !last_pk )
log_error("Ooops: no seckey for userid '%.*s'\n",
pkt.pkt.user_id->len, pkt.pkt.user_id->name);
else {
if( last_pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|| last_pk->pubkey_algo == PUBKEY_ALGO_DSA
|| last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
keyid_from_skc( last_pk, akeyid );
cache_user_id( pkt.pkt.user_id, akeyid );
}
else { /* keyid or fingerprint lookup */
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_PUBLIC_CERT
|| k->pkt->pkttype == PKT_PUBKEY_SUBCERT ) {
if( mode == 10 || mode == 11 ) {
u32 aki[2];
keyid_from_pkc( k->pkt->pkt.public_cert, aki );
if( aki[1] == keyid[1]
&& ( mode == 10 || aki[0] == keyid[0] )
&& ( !pkc->pubkey_algo
|| pkc->pubkey_algo
== k->pkt->pkt.public_cert->pubkey_algo) ){
/* cache the userid */
for(kk=keyblock; kk; kk = kk->next )
if( kk->pkt->pkttype == PKT_USER_ID )
break;
if( kk )
cache_user_id( kk->pkt->pkt.user_id, aki );
else
log_error("No userid for key\n");
break; /* found */
}
}
else if( mode == 15 ) { /* get the first key */
if( !pkc->pubkey_algo
|| pkc->pubkey_algo
== k->pkt->pkt.public_cert->pubkey_algo )
break;
}
else if( mode == 16 || mode == 20 ) {
size_t an;
byte *afp = fingerprint_from_pkc(
k->pkt->pkt.public_cert, &an );
if( an == mode && !memcmp( afp, name, an)
&& ( !pkc->pubkey_algo
|| pkc->pubkey_algo
== k->pkt->pkt.public_cert->pubkey_algo) ) {
m_free(afp);
break;
}
m_free(afp);
}
else
BUG();
} /* end compare public keys */
}
}
free_packet(&pkt);
if( k ) { /* found */
assert( k->pkt->pkttype == PKT_PUBLIC_CERT
|| k->pkt->pkttype == PKT_PUBKEY_SUBCERT );
copy_public_cert( pkc, k->pkt->pkt.public_cert );
break; /* enumeration */
}
release_kbnode( keyblock );
keyblock = NULL;
}
rc = G10ERR_NO_SECKEY;
if( rc == -1 )
rc = G10ERR_NO_PUBKEY;
else if( rc )
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
leave:
if( last_pk )
free_secret_cert(last_pk);
free_packet(&pkt);
iobuf_close(a);
set_packet_list_mode(save_mode);
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock );
return rc;
}
/****************
* Ditto for secret keys
*/
static int
lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name )
{
int rc;
KBNODE keyblock = NULL;
KBPOS kbpos;
rc = enum_keyblocks( 5 /* open secret */, &kbpos, &keyblock );
if( rc ) {
if( rc == -1 )
rc = G10ERR_NO_PUBKEY;
else if( rc )
log_error("enum_keyblocks(open secret) failed: %s\n", g10_errstr(rc) );
goto leave;
}
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
KBNODE k, kk;
if( mode < 10 ) { /* name lookup */
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_USER_ID
&& !compare_name( k->pkt->pkt.user_id->name,
k->pkt->pkt.user_id->len, name, mode)) {
/* we found a matching name, look for the key */
for(kk=keyblock; kk; kk = kk->next )
if( ( kk->pkt->pkttype == PKT_SECRET_CERT
|| kk->pkt->pkttype == PKT_SECKEY_SUBCERT )
&& ( !skc->pubkey_algo
|| skc->pubkey_algo
== kk->pkt->pkt.secret_cert->pubkey_algo))
break;
if( kk ) {
u32 aki[2];
keyid_from_skc( kk->pkt->pkt.secret_cert, aki );
cache_user_id( k->pkt->pkt.user_id, aki );
k = kk;
break;
}
else
log_error("No key for userid (in skc)\n");
}
}
}
else { /* keyid or fingerprint lookup */
for(k=keyblock; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SECRET_CERT
|| k->pkt->pkttype == PKT_SECKEY_SUBCERT ) {
if( mode == 10 || mode == 11 ) {
u32 aki[2];
keyid_from_skc( k->pkt->pkt.secret_cert, aki );
if( aki[1] == keyid[1]
&& ( mode == 10 || aki[0] == keyid[0] )
&& ( !skc->pubkey_algo
|| skc->pubkey_algo
== k->pkt->pkt.secret_cert->pubkey_algo) ){
/* cache the userid */
for(kk=keyblock; kk; kk = kk->next )
if( kk->pkt->pkttype == PKT_USER_ID )
break;
if( kk )
cache_user_id( kk->pkt->pkt.user_id, aki );
else
log_error("No userid for key\n");
break; /* found */
}
}
else if( mode == 15 ) { /* get the first key */
if( !skc->pubkey_algo
|| skc->pubkey_algo
== k->pkt->pkt.secret_cert->pubkey_algo )
break;
}
else if( mode == 16 || mode == 20 ) {
size_t an;
byte *afp = fingerprint_from_skc(
k->pkt->pkt.secret_cert, &an );
if( an == mode && !memcmp( afp, name, an)
&& ( !skc->pubkey_algo
|| skc->pubkey_algo
== k->pkt->pkt.secret_cert->pubkey_algo) ) {
m_free(afp);
break;
}
m_free(afp);
}
else
BUG();
} /* end compare secret keys */
}
}
if( k ) { /* found */
assert( k->pkt->pkttype == PKT_SECRET_CERT
|| k->pkt->pkttype == PKT_SECKEY_SUBCERT );
copy_secret_cert( skc, k->pkt->pkt.secret_cert );
break; /* enumeration */
}
release_kbnode( keyblock );
keyblock = NULL;
}
if( rc == -1 )
rc = G10ERR_NO_PUBKEY;
else if( rc )
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
leave:
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock );
return rc;
}
/****************
* Enumerate all secret keys. Caller must use these procedure:

View File

@ -52,6 +52,7 @@ struct keyblock_pos_struct {
ulong offset; /* position information */
unsigned count; /* length of the keyblock in packets */
IOBUF fp; /* used by enum_keyblocks */
int secret; /* working on a secret keyring */
PACKET *pkt; /* ditto */
};
typedef struct keyblock_pos_struct KBPOS;
@ -102,8 +103,8 @@ int make_dek_from_passphrase( DEK *dek, int mode, byte *salt );
void add_keyring( const char *name );
const char *get_keyring( int sequence );
void add_secret_keyring( const char *name );
void cache_public_cert( PKT_public_cert *pkc );
void cache_user_id( PKT_user_id *uid, u32 *keyid );
/*void cache_public_cert( PKT_public_cert *pkc );
void cache_user_id( PKT_user_id *uid, u32 *keyid );*/
int get_pubkey( PKT_public_cert *pkc, u32 *keyid );
int get_pubkey_byname( PKT_public_cert *pkc, const char *name );
int get_seckey( PKT_secret_cert *skc, u32 *keyid );

View File

@ -105,6 +105,56 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
return md;
}
static MD_HANDLE
elg_fingerprint_md( PKT_public_cert *pkc )
{
MD_HANDLE md;
byte *buf1, *buf3, *buf4 ;
byte *p1, *p3, *p4;
unsigned n1, n3, n4;
unsigned nb1, nb3, nb4;
unsigned n;
nb1 = mpi_get_nbits(pkc->d.dsa.p);
p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL );
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
;
nb3 = mpi_get_nbits(pkc->d.dsa.g);
p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL );
for( ; !*p3 && n3; p3++, n3-- )
;
nb4 = mpi_get_nbits(pkc->d.dsa.y);
p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL );
for( ; !*p4 && n4; p4++, n4-- )
;
/* calculate length of packet */
n = 12 + n1 + n3 +n4 ;
md = md_open( DIGEST_ALGO_SHA1, 0);
md_putc( md, 0x99 ); /* ctb */
md_putc( md, n >> 8 ); /* 2 byte length header */
md_putc( md, n );
md_putc( md, 4 ); /* version */
{ u32 a = pkc->timestamp;
md_putc( md, a >> 24 );
md_putc( md, a >> 16 );
md_putc( md, a >> 8 );
md_putc( md, a );
}
md_putc( md, pkc->pubkey_algo );
md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 );
m_free(buf1);
m_free(buf3);
m_free(buf4);
md_final( md );
return md;
}
static MD_HANDLE
dsa_fingerprint_md( PKT_public_cert *pkc )
{
@ -161,18 +211,22 @@ dsa_fingerprint_md( PKT_public_cert *pkc )
}
static MD_HANDLE
v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
elg_fingerprint_md_skc( PKT_secret_cert *skc )
{
PKT_public_cert pkc;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.version = skc->version;
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.elg.p = skc->d.elg.p;
pkc.d.elg.g = skc->d.elg.g;
pkc.d.elg.y = skc->d.elg.y;
return v3_elg_fingerprint_md( &pkc );
if( pkc.version < 4 )
return v3_elg_fingerprint_md( &pkc );
else
return elg_fingerprint_md( &pkc );
}
static MD_HANDLE
@ -207,8 +261,11 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
const byte *dp;
MD_HANDLE md;
md = v3_elg_fingerprint_md_skc(skc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
md = elg_fingerprint_md_skc(skc);
if( skc->version < 4 )
dp = md_read( md, DIGEST_ALGO_RMD160 );
else
dp = md_read( md, DIGEST_ALGO_SHA1 );
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
@ -250,14 +307,20 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
const byte *dp;
MD_HANDLE md;
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
if( pkc->version < 4 ) {
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
}
else {
md = elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
}
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1];
md_close(md);
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
const byte *dp;
MD_HANDLE md;
md = dsa_fingerprint_md(pkc);
@ -380,6 +443,7 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
byte *p;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.version = skc->version;
if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
@ -419,8 +483,14 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
MD_HANDLE md;
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
if( pkc->version < 4 ) {
md = v3_elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_RMD160 );
}
else {
md = elg_fingerprint_md(pkc);
dp = md_read( md, DIGEST_ALGO_SHA1 );
}
array = m_alloc( 20 );
len = 20;
memcpy(array, dp, 20 );

View File

@ -107,6 +107,7 @@ list_one( const char *name )
goto leave;
}
/* get the keyid from the keyblock */
node = find_kbnode( keyblock, PKT_PUBLIC_CERT );
if( !node ) {

View File

@ -113,4 +113,7 @@ int decrypt_message( const char *filename );
/*-- plaintext.c --*/
int hash_datafiles( MD_HANDLE md, STRLIST files, int textmode );
/*-- signal.c --*/
void init_signals(void);
#endif /*G10_MAIN_H*/

View File

@ -706,7 +706,7 @@ check_sig_and_print( CTX c, KBNODE node )
log_info("%s signature from ", rc? "BAD":"Good");
print_keyid( stderr, sig->keyid );
putc('\n', stderr);
if( opt.batch )
if( opt.batch && rc )
g10_exit(1);
}
else {

View File

@ -50,6 +50,7 @@ typedef struct packet_struct PACKET;
typedef struct {
u32 keyid[2]; /* 64 bit keyid */
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
union {
struct {

View File

@ -425,7 +425,6 @@ skip_rest( IOBUF inp, unsigned long pktlen )
static int
parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
int version;
unsigned n;
PKT_pubkey_enc *k;
@ -434,17 +433,17 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
log_error("packet(%d) too short\n", pkttype);
goto leave;
}
version = iobuf_get_noeof(inp); pktlen--;
if( version != 2 && version != 3 ) {
log_error("packet(%d) with unknown version %d\n", pkttype, version);
k->version = iobuf_get_noeof(inp); pktlen--;
if( k->version != 2 && k->version != 3 ) {
log_error("packet(%d) with unknown version %d\n", pkttype, k->version);
goto leave;
}
k->keyid[0] = read_32(inp); pktlen -= 4;
k->keyid[1] = read_32(inp); pktlen -= 4;
k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
if( list_mode )
printf(":public key encoded packet: keyid %08lX%08lX\n",
(ulong)k->keyid[0], (ulong)k->keyid[1]);
printf(":public key encoded packet: version %d, keyid %08lX%08lX\n",
k->version, (ulong)k->keyid[0], (ulong)k->keyid[1]);
if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
n = pktlen;
k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
@ -791,7 +790,10 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( list_mode )
printf(":%s key packet:\n"
"\tversion %d, created %lu, valid for %hu days\n",
pkttype == PKT_PUBLIC_CERT? "public": "secret",
pkttype == PKT_PUBLIC_CERT? "public" :
pkttype == PKT_SECRET_CERT? "secret" :
pkttype == PKT_PUBKEY_SUBCERT? "public sub" :
pkttype == PKT_SECKEY_SUBCERT? "secret sub" : "??",
version, timestamp, valid_period );
if( pkttype == PKT_SECRET_CERT ) {
pkt->pkt.secret_cert->timestamp = timestamp;

View File

@ -78,7 +78,7 @@ static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf,
static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos,
const char *fname);
static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root );
static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
@ -346,11 +346,13 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
* Mode is: 0 = open
* 1 = read
* 2 = close
* 5 = open secret keyrings
* 11 = read but skip signature and comment packets.
* all others are reserved!
* Note that you do not need a search prior to call this function,
* only handle is needed.
* NOTE: It is not alloed to do an insert/update/delte with this
* keyblock, if you want to do this, user search/read!
* Note that you do not need a search prior to this function,
* only a handle is needed.
* NOTE: It is not allowed to do an insert/update/delte with this
* keyblock, if you want to do this, use search/read!
*/
int
enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
@ -358,15 +360,23 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
int rc = 0;
RESTBL *rentry;
if( !mode || mode == 100 ) {
if( !mode || mode == 5 || mode == 100 ) {
int i;
kbpos->fp = NULL;
if( !mode )
if( !mode ) {
kbpos->secret = 0;
i = 0;
}
else if( mode == 5 ) {
kbpos->secret = 1;
mode = 0;
i = 0;
}
else
i = kbpos->resno+1;
for(; i < MAX_RESOURCES; i++ )
if( resource_table[i].used && !resource_table[i].secret )
if( resource_table[i].used
&& !resource_table[i].secret == !kbpos->secret )
break;
if( i == MAX_RESOURCES )
return -1; /* no resources */
@ -379,13 +389,13 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
}
kbpos->pkt = NULL;
}
else if( mode == 1 ) {
else if( mode == 1 || mode == 11 ) {
int cont;
do {
cont = 0;
if( !kbpos->fp )
return G10ERR_GENERAL;
rc = keyring_enum( kbpos, ret_root );
rc = keyring_enum( kbpos, ret_root, mode == 11 );
if( rc == -1 ) {
assert( !kbpos->pkt );
rentry = check_pos( kbpos );
@ -703,13 +713,12 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
static int
keyring_enum( KBPOS *kbpos, KBNODE *ret_root )
keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
{
PACKET *pkt;
int rc;
RESTBL *rentry;
KBNODE root = NULL;
int in_cert = 0;
if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL;
@ -736,17 +745,28 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root )
switch( pkt->pkttype ) {
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
if( in_cert ) { /* store this packet */
if( root ) { /* store this packet */
kbpos->pkt = pkt;
pkt = NULL;
goto ready;
}
in_cert = 1;
root = new_kbnode( pkt );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;
default:
if( !root )
root = new_kbnode( pkt );
else
add_kbnode( root, new_kbnode( pkt ) );
/* skip pakets at the begin of a keyring, until we find
* a start packet; issue a warning if it is not a comment */
if( !root && pkt->pkttype != PKT_COMMENT )
log_info("keyring_enum: skipped packet of type %d\n",
pkt->pkttype );
if( !root || (skipsigs && ( pkt->pkttype == PKT_SIGNATURE
||pkt->pkttype == PKT_COMMENT )) ) {
init_packet(pkt);
break;
}
add_kbnode( root, new_kbnode( pkt ) );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;

View File

@ -63,6 +63,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
MPI result = NULL;
int rc=0;
if( pkc->timestamp > sig->timestamp )
return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
ELG_public_key pkey;
@ -96,8 +100,6 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
* signature */
md_enable( digest, sig->digest_algo );
assert( sig->digest_algo == DIGEST_ALGO_SHA1 );
/* complete the digest */
if( sig->version >= 4 )
md_putc( digest, sig->version );
@ -117,10 +119,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
if( sig->hashed_data ) {
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
md_write( digest, sig->hashed_data, n+2 );
n += 4;
n += 6;
}
else
n = 4;
n = 6;
/* add some magic */
buf[0] = sig->version;
buf[1] = 0xff;
@ -131,8 +133,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
md_write( digest, buf, 6 );
}
md_final( digest );
log_hexdump("digest is: ", md_read(digest, DIGEST_ALGO_SHA1), 20);
result = encode_md_value( digest, mpi_get_nbits(pkc->d.dsa.p));
result = mpi_alloc( (md_digest_length(sig->digest_algo)
+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
mpi_set_buffer( result, md_read(digest, DIGEST_ALGO_SHA1),
md_digest_length(sig->digest_algo), 0 );
pkey.p = pkc->d.dsa.p;
pkey.q = pkc->d.dsa.q;
pkey.g = pkc->d.dsa.g;
@ -288,13 +292,11 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
keyid_from_pkc( pkc, keyid );
md = md_open( algo, 0 );
if( sig->sig_class== 16 )
md->debug = fopen("dsahashsig","w");
hash_public_cert( md, pkc );
if( sig->version >=4 ) {
byte buf[5];
buf[0] = 0xb4; /* indicates a userid packet */
buf[1] = uid->len >> 24; /* but use 4 length bytes */
buf[1] = uid->len >> 24; /* always use 4 length bytes */
buf[2] = uid->len >> 16;
buf[3] = uid->len >> 8;
buf[4] = uid->len;
@ -309,8 +311,6 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
else
rc = signature_check( sig, md );
md_close(md);
if( sig->sig_class== 16 )
fclose(md->debug);
}
else {
log_error("no user id for key signature packet\n");

View File

@ -871,8 +871,8 @@ delete_key( const char *username, int secret )
KBNODE keyblock = NULL;
KBNODE node;
KBPOS kbpos;
PKT_public_cert *pkc;
PKT_secret_cert *skc;
PKT_public_cert *pkc = NULL;
PKT_secret_cert *skc = NULL;
u32 keyid[2];
int okay=0;

74
g10/signal.c Normal file
View File

@ -0,0 +1,74 @@
/* signal.c - signal handling
* Copyright (C) 1998 Free Software Foundation, Inc.
*
* This file is part of GNUPG.
*
* GNUPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GNUPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "options.h"
#include "errors.h"
#include "memory.h"
#include "util.h"
#include "main.h"
#include "ttyio.h"
static RETSIGTYPE
print_and_exit( int sig )
{
const char *p;
/* Hmm, use only safe functions (we should do an autoconf test) */
write( 2, "\nCaught ", 8 );
#if SYS_SIGLIST_DECLARED
p = sys_siglist[sig];
write( 2, p, strlen(p) );
#else
write( 2, "a signal", 8 );
#endif
write( 2, "... exiting\n", 12 );
secmem_term();
exit(2); /* not correct but .. */
}
void
init_signals()
{
#if 0
struct sigaction nact;
nact.sa_handler = print_and_exit;
sigemptyset (&nact.sa_mask);
nact.sa_flags = 0;
sigaction( SIGINT, &nact, NULL );
sigaction( SIGHUP, &nact, NULL );
sigaction( SIGTERM, &nact, NULL );
#endif
}

View File

@ -1388,8 +1388,8 @@ propagate_trust( TRUST_SEG_LIST tslist )
/****************
* we have the pubkey record but nothing more is known
* function may re-read dr.
* we have the pubkey record but nothing more is known.
* (function may re-read dr)
*/
static int
do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
@ -1736,7 +1736,11 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
pkc->local_id );
}
}
/* fixme: do some additional checks on the pubkey record */
if( pkc->timestamp > make_timestamp() ) {
log_info("public key created in future (time warp or clock problem)\n");
return G10ERR_TIME_CONFLICT;
}
rc = do_check( pkc->local_id, &rec, &trustlevel );
if( rc ) {

View File

@ -59,5 +59,6 @@
#define G10ERR_RENAME_FILE 37
#define G10ERR_DELETE_FILE 38
#define G10ERR_UNEXPECTED 39
#define G10ERR_TIME_CONFLICT 40
#endif /*G10_ERRORS_H*/

View File

@ -25,7 +25,7 @@
#include <locale.h> /* suggested by Ernst Molitor */
#endif
#ifdef HAVE_LIBINTL
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(a) gettext (a)
#ifdef gettext_noop

View File

@ -149,6 +149,7 @@ unsigned mpi_get_nbits( MPI a );
int mpi_test_bit( MPI a, unsigned n );
void mpi_set_bit( MPI a, unsigned n );
void mpi_set_highbit( MPI a, unsigned n );
void mpi_clear_highbit( MPI a, unsigned n );
void mpi_clear_bit( MPI a, unsigned n );
void mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque );
void mpi_rshift( MPI x, MPI a, unsigned n );

View File

@ -1,3 +1,7 @@
Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi-bit.c (mpi_clear_highbit): New.
Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
* Makefile.am (DISTCLEANFILES): New

View File

@ -134,6 +134,25 @@ mpi_set_highbit( MPI a, unsigned n )
a->nlimbs = limbno+1;
}
/****************
* clear bit N of A and all bits above
*/
void
mpi_clear_highbit( MPI a, unsigned n )
{
unsigned limbno, bitno;
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
if( limbno >= a->nlimbs )
return; /* not allocated, so need to clear bits :-) */
for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
a->d[limbno] &= ~(A_LIMB_1 << bitno);
a->nlimbs = limbno+1;
}
/****************
* Clear bit N of A.
*/

View File

@ -1 +1,5 @@
Fri Mar 13 09:43:19 1998 Werner Koch (wk@isil.d.shuttle.de)
* it.po: New

View File

@ -56,34 +56,8 @@ msgstr ""
"Die voreingestellte Operation ist abhängig von den Eingabedaten\n"
#: g10/g10.c:77
msgid "Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n"
msgstr "Berichte über Wanzen bitte an <g10-bugs@isil.d.shuttle.de>.\n"
#: g10/g10.c:82
msgid ""
" NOTE: This version is compiled without ZLIB support;\n"
" you are not able to process compresssed data!\n"
"WARNING: This version has RSA support! Your are not allowed to\n"
" use it inside the Unites States before Sep 30, 2000!\n"
msgstr ""
"Achtung: Komprimierte Daten können nicht bearbeiten werden,\n"
" da auf diesem System ZLIN nicht installiert ist!\n"
" (RSA Verfahren ist vorhanden.)\n"
#: g10/g10.c:88
msgid ""
" NOTE: This version is compiled without ZLIB support;\n"
" you are not able to process compresssed data!\n"
msgstr ""
"Achtung: Komprimierte Daten können nicht bearbeiten werden,\n"
" da auf diesem System ZLIB nicht installiert ist!\n"
#: g10/g10.c:92
msgid ""
"WARNING: This version has RSA support! Your are not allowed to\n"
" use it inside the Unites States before Sep 30, 2000!\n"
msgstr ""
" (RSA Verfahren ist vorhanden.)\n"
msgid "Please report bugs to <gnupg-bugs@isil.d.shuttle.de>.\n"
msgstr "Berichte über Wanzen bitte an <gnupg-bugs@isil.d.shuttle.de>.\n"
#: g10/g10.c:116
msgid "Usage: g10 [options] "
@ -131,7 +105,7 @@ msgstr "\"Nein\" als Standard Antwort annehmen"
#: g10/g10.c:173
msgid "generate a new key pair"
msgstr "Einen neues Schlüsselpaar erzeugen"
msgstr "Ein neues Schlüsselpaar erzeugen"
#: g10/g10.c:174
msgid "add key to the public keyring"

726
po/it.po Normal file
View File

@ -0,0 +1,726 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=iso-8859-1\n"
"Date: 1998-03-07 12:16:14+0100\n"
"From: Marco d'Itri <md@linux.it>\n"
"Xgettext-Options: --default-domain=gnupg --directory=.. --add-comments "
"--keyword=_ --keyword=N_ --files-from=./POTFILES.in\n"
"Files: util/secmem.c cipher/random.c g10/g10.c g10/pkclist.c g10/keygen.c\n"
#: util/secmem.c:180
msgid "Warning: using insecure memory!\n"
msgstr "Attenzione: si sta usando memoria insicura!\n"
#: cipher/random.c:419
msgid ""
"\n"
"Not enough random bytes available. Please do some other work to give\n"
"the OS a chance to collect more entropy! (Need %d more bytes)\n"
msgstr ""
"\n"
"Non ci sono abbastanza byte casuali disponibili. Per favore fai\n"
"qualche altro lavoro per dare al sistema operativo un'occasione per\n"
"raccogliere altra entropia! (Servono ancora %d byte)\n"
#: cipher/random.c:459
msgid "warning: using insecure random number generator!!\n"
msgstr "Attenzione: si sta usando un generatore di numeri casuali insicuro!!\n"
# #### Md - kludge?
#: cipher/random.c:460
msgid ""
"The random number generator is only a kludge to let\n"
"it compile - it is in no way a strong RNG!\n"
"\n"
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n"
"\n"
msgstr ""
"Il generatore di numeri casuali è solo un ripiego usato\n"
"per compilare il programma - non è assolutamente un forte RNG!\n"
"\n"
"NON USARE ALCUN DATO GENERATO DA QUESTO PROGRAMMA!!\n"
"\n"
#: g10/g10.c:56
msgid ""
"\\vCommands:\n"
" "
msgstr ""
"\\vComandi:\n"
" "
#: g10/g10.c:59
msgid "make a signature"
msgstr "fai una firma"
#: g10/g10.c:60
msgid "make a clear text signature"
msgstr "fai una firma al testo in chiaro"
#: g10/g10.c:61
msgid "make a detached signature"
msgstr "fai una firma separata"
#: g10/g10.c:62
msgid "encrypt data"
msgstr "cifra dati"
#: g10/g10.c:63
msgid "encryption only with symmetric cipher"
msgstr "cifra solo con un cifrario simmetrico"
#: g10/g10.c:64
msgid "store only"
msgstr "immagazzina solo"
#: g10/g10.c:65
msgid "decrypt data (default)"
msgstr "decifra dati (predefinito)"
#: g10/g10.c:66
msgid "verify a signature"
msgstr "verifica una firma"
#: g10/g10.c:68
msgid "list keys"
msgstr "elenca le chiavi"
#: g10/g10.c:69
msgid "list keys and signatures"
msgstr "elenca le chiavi e le firme"
#: g10/g10.c:70
msgid "check key signatures"
msgstr "controlla le firme delle chiavi"
#: g10/g10.c:71
msgid "list keys and fingerprints"
msgstr "elenca le chiavi e le impronte digitali"
#: g10/g10.c:73
msgid "generate a new key pair"
msgstr "genera una nuova coppia di chiavi"
#: g10/g10.c:74
msgid "make a signature on a key in the keyring"
msgstr "firma una chiave nel portachiavi"
#: g10/g10.c:75
msgid "remove key from the public keyring"
msgstr "rimuovi una chiave dal portachiavi pubblico"
#: g10/g10.c:76
msgid "edit a key signature"
msgstr "modifica la firma di una chiave"
#: g10/g10.c:77
msgid "change the passphrase of your secret keyring"
msgstr "cambia la passphrase del tuo portachiavi segreto"
#: g10/g10.c:78
msgid "generate a revocation certificate"
msgstr "genera un certificato di revoca"
#: g10/g10.c:80
msgid "export keys"
msgstr "esporta delle chiavi"
#: g10/g10.c:81
msgid "import/merge keys"
msgstr "importa/aggiungi delle chiavi"
#: g10/g10.c:82
msgid "list only the sequence of packets"
msgstr "elenca solo la sequenza dei pacchetti"
#: g10/g10.c:84
msgid "De-Armor a file or stdin"
msgstr "rimuovi l'armatura a un file o a stdin"
#: g10/g10.c:85
msgid "En-Armor a file or stdin"
msgstr "crea l'armatura a un file o a stdin"
#: g10/g10.c:86
msgid "print all message digests"
msgstr "stampa tutti i message digests"
#: g10/g10.c:91
msgid ""
"\\v\n"
"Options:\n"
" "
msgstr ""
"\\v\n"
"Opzioni:\n"
" "
#: g10/g10.c:94
msgid "create ascii armored output"
msgstr "crea un output ascii con armatura"
#: g10/g10.c:95
msgid "use this user-id to sign or decrypt"
msgstr "usa questo user-id per firmare o decifrare"
#: g10/g10.c:96
msgid "use this user-id for encryption"
msgstr "usa questo user-id per cifrare"
#: g10/g10.c:97
msgid "set compress level (0 disables)"
msgstr "imposta il livello di compressione (0 disabilita)"
#: g10/g10.c:98
msgid "use canonical text mode"
msgstr "usa il modo testo canonico"
#: g10/g10.c:100
msgid "use as output file"
msgstr "usa come un file di output"
#: g10/g10.c:101
msgid "verbose"
msgstr "prolisso"
#: g10/g10.c:102
msgid "don't make any changes"
msgstr "non fare cambiamenti"
#: g10/g10.c:103
msgid "batch mode: never ask"
msgstr "modo batch: non fare domande"
#: g10/g10.c:104
msgid "assume yes on most questions"
msgstr "assumi \"si\" a quasi tutte le domande"
#: g10/g10.c:105
msgid "assume no on most questions"
msgstr "assumi \"no\" a quasi tutte le domande"
#: g10/g10.c:106
msgid "add this keyring to the list of keyrings"
msgstr "aggiungi questo portachiavi alla lista dei portachiavi"
#: g10/g10.c:107
msgid "add this secret keyring to the list"
msgstr "aggiungi questo portachiavi segreto alla lista"
#: g10/g10.c:108
msgid "read options from file"
msgstr "leggi le opzioni dal file"
#: g10/g10.c:110
msgid "set debugging flags"
msgstr "imposa i flag di debugging"
#: g10/g10.c:111
msgid "enable full debugging"
msgstr "abilita il debugging completo"
#: g10/g10.c:112
msgid "write status info to this fd"
msgstr "scrivi le informazioni di stato su questo fd"
#: g10/g10.c:113
msgid "do not write comment packets"
msgstr "non scrivere pacchetti di commento"
#: g10/g10.c:114
msgid "(default is 1)"
msgstr "(predefinito è 1)"
#: g10/g10.c:115
msgid "(default is 3)"
msgstr "(predefinito è 3)"
#: g10/g10.c:117
msgid "select default cipher algorithm"
msgstr "seleziona l'algoritmo di cifratura predefinito"
#: g10/g10.c:118
msgid "select default puplic key algorithm"
msgstr "seleziona l'algoritmo a chiave pubblica predefinito"
#: g10/g10.c:119
msgid "select default message digest algorithm"
msgstr "seleziona l'algoritmo di message digest predefinito"
#: g10/g10.c:123
msgid ""
"\\v\n"
"Examples:\n"
"\n"
" -se -r Bob [file] sign and encrypt for user Bob\n"
" -sat [file] make a clear text signature\n"
" -sb [file] make a detached signature\n"
" -k [userid] show keys\n"
" -kc [userid] show fingerprint\n"
msgstr ""
"\\v\n"
"Esempi:\n"
"\n"
" -se -r Bob [file] firma e cifra per l'utente Bob\n"
" -sat [file] fai una firma al testo in chiaro\n"
" -sb [file] fai una firma separata\n"
" -k [userid] mostra le chiavi\n"
" -kc [userid] mostra le impronte digitali\n"
#: g10/g10.c:201
msgid "Please report bugs to <gnupg-bugs@isil.d.shuttle.de>.\n"
msgstr "Per favore segnala i bug a <gnupg-bugs@isil.d.shuttle.de>.\n"
#: g10/g10.c:206
msgid "Usage: gpgm [options] [files] (-h for help)"
msgstr "Uso: gpgm [opzioni] [file] (-h per l'aiuto)"
#: g10/g10.c:208
msgid "Usage: gpg [options] [files] (-h for help)"
msgstr "Uso: gpg [opzioni] [file] (-h per l'aiuto)"
#: g10/g10.c:213
msgid ""
"Syntax: gpgm [options] [files]\n"
"GNUPG maintenance utility\n"
msgstr ""
"Sintassi: gpgm [opzioni] [file]\n"
"Utility di manutenzione di GNUPG\n"
#: g10/g10.c:216
msgid ""
"Syntax: gpg [options] [files]\n"
"sign, check, encrypt or decrypt\n"
"default operation depends on the input data\n"
msgstr ""
"Sintassi: gpg [opzioni] [file]\n"
"firma, controlla, cifra o decifra\n"
"l'operazione predefinita dipende dai dati di input\n"
#: g10/g10.c:293
msgid "usage: gpgm [options] "
msgstr "uso: gpgm [options] "
#: g10/g10.c:295
msgid "usage: gpg [options] "
msgstr "uso: gpg [options] "
#: g10/g10.c:335
msgid "conflicting commands\n"
msgstr "comandi in conflitto\n"
#: g10/g10.c:348
msgid "selected cipher algorithm is invalid\n"
msgstr "l'algoritmo di cifratura selezionato non è valido\n"
#: g10/g10.c:350
msgid "selected pubkey algorithm is invalid\n"
msgstr "l'algoritmo a chiave pubblica selezionato non è valido\n"
#: g10/g10.c:352
msgid "selected digest algorithm is invalid\n"
msgstr "l'algoritmo di digest selezionato non è valido\n"
#: g10/g10.c:354
msgid "completes-needed must be greater than 0\n"
msgstr "completes-needed deve essere maggiore di 0\n"
#: g10/g10.c:356
msgid "marginals-needed must be greater than 1\n"
msgstr "marginals-needed deve essere maggiore di 1\n"
#: g10/g10.c:450
msgid "note: no default option file '%s'\n"
msgstr "nota: nessun file con opzioni predefinite '%s'\n"
#: g10/g10.c:454
msgid "option file '%s': %s\n"
msgstr "file con opzioni predefinite '%s': %s\n"
#: g10/g10.c:461
msgid "reading options from '%s'\n"
msgstr "lettura delle opzioni da '%s'\n"
#: g10/g10.c:657
msgid "failed to initialize the TrustDB: %s\n"
msgstr "inizializzazione del TrustDB fallita: %s\n"
#: g10/g10.c:663
msgid "--store [filename]"
msgstr "--store [nomefile]"
#. encrypt the given file only with the symmetric cipher
#: g10/g10.c:671
msgid "--symmetric [filename]"
msgstr " [nomefile]"
#: g10/g10.c:679
msgid "--encrypt [filename]"
msgstr "--encrypt [nomefile]"
#: g10/g10.c:692
msgid "--sign [filename]"
msgstr "--sign [nomefile]"
#: g10/g10.c:705
msgid "--sign --encrypt [filename]"
msgstr "--sign --encrypt [nomefile]"
#. make a clearsig
#: g10/g10.c:719
msgid "--clearsign [filename]"
msgstr "--clearsign [nomefile]"
#: g10/g10.c:731
msgid "--decrypt [filename]"
msgstr "--decrypt [nomefile]"
#: g10/g10.c:739
msgid "--sign-key username"
msgstr ""
#: g10/g10.c:747
msgid "--edit-sig username"
msgstr ""
#: g10/g10.c:755
msgid "--delete-secret-key username"
msgstr ""
#: g10/g10.c:758
msgid "--delete-key username"
msgstr ""
#. no arg: use default, 1 arg use this one
#: g10/g10.c:766
msgid "--change-passphrase [username]"
msgstr ""
#: g10/g10.c:787
msgid "can't open %s: %s\n"
msgstr "impossibile aprire '%s': %s\n"
#: g10/g10.c:798
msgid "-k[v][v][v][c] [userid] [keyring]"
msgstr "-k[v][v][v][c] [userid] [portachiavi]"
#: g10/g10.c:804
msgid "--gen-key"
msgstr ""
#: g10/g10.c:845
msgid "dearmoring failed: %s\n"
msgstr "rimozione dell'armatura fallita: %s\n"
#: g10/g10.c:853
msgid "enarmoring failed: %s\n"
msgstr "creazione dell'armatura fallita: %s\n"
#. fixme: g10maint should to regular maintenace tasks here
#: g10/g10.c:934
msgid "[filename]"
msgstr "[nomefile]"
#: g10/g10.c:936
msgid "can't open '%s'\n"
msgstr "impossibile aprire '%s'"
# #### Md ???
#: g10/pkclist.c:65
msgid ""
"No ownertrust defined for %lu:\n"
"%4u%c/%08lX %s \""
msgstr ""
"Nessun valore di fiducia del proprietario definito per %lu:\n"
"%4u%c/%08lX %s \""
#: g10/pkclist.c:72
msgid ""
"\"\n"
"\n"
"Please decide in how far do you trust this user to\n"
"correctly sign other users keys (looking at his passport,\n"
"checking the fingerprints from different sources ...)?\n"
"\n"
" 1 = Don't know\n"
" 2 = I do NOT trust\n"
" 3 = I trust marginally\n"
" 4 = I trust fully\n"
" s = please show me more informations\n"
"\n"
msgstr ""
"\"\n"
"\n"
"Per favore decidi fino a quanto hai fiducia di questo utente perchè\n"
firmi correttamente le chiavi di altri utenti (guardando il suo\n"
passaporto, controllando le impronte digitali da diverse fonti ...)?\n"
"\n"
" 1 = Non lo so\n"
" 2 = NON mi fido\n"
" 3 = Mi fido marginalmente\n"
" 4 = Mi fido completamente\n"
" s = mostrami ulteriori informazioni\n"
"\n"
#: g10/pkclist.c:83
msgid "Your decision? "
msgstr "La tua decisione? "
#: g10/pkclist.c:90
msgid ""
"It's up to you to assign a value here; this value will never be exported\n"
"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n"
"to do with the (implicitly created) web-of-certificates.\n"
msgstr ""
"È compito tuo assegnare qui un valore; questo valore non sarà mai esportato\n"
"ad alcuna terza persona. Ci serve per implementare la ragnatela-di-fiducia;\n"
"non ha nulla a che fare con la ragnatela-di-certificati (creata
implicitamente).\n"
#: g10/pkclist.c:108
msgid "You will see a list of signators etc. here\n"
msgstr "Qui vedrai una lista di firmatari, ecc...\n"
#: g10/pkclist.c:132
msgid ""
"Could not find a valid trust path to the key. Lets see, wether we\n"
"can assign some missing owner trust values.\n"
"\n"
msgstr ""
"Impossibile trovare un percorso di fiducia valido fino alla chiave. Vediamo\n"
"se possiamo assegnare qualche valore di fiducia del proprietario mancante.\n"
"\n"
#: g10/pkclist.c:157
msgid ""
"No ownertrust values changed.\n"
"\n"
msgstr ""
"Nessun valore di fiducia del proprietario modificato.\n"
"\n"
#: g10/pkclist.c:267
msgid ""
"It is NOT certain, that the key belongs to his owner.\n"
"If you *really* know what you are doing, you may answer\n"
"the next question with yes\n"
"\n"
msgstr "NON è sicuro che la chiave appartenga al suo proprietario.\n"
"Se *veramente* sai cosa stai facendo, puoi rispondere si alla\n"
"prossima domanda.\n"
"\n"
#: g10/pkclist.c:304
msgid ""
"You did not specify a user ID. (you may use \"-r\")\n"
"\n"
msgstr ""
"Non hai specificato un user ID. (puoi usare \"-r\")\n"
"\n"
#: g10/pkclist.c:308
msgid "Enter the user ID: "
msgstr "Inserisci l'user ID: "
#: g10/keygen.c:109
msgid "writing self signature\n"
msgstr "scrittura della autofirma\n"
#: g10/keygen.c:303
msgid "Key generation can only be used in interactive mode\n"
msgstr "Una chiave può essere generata solo in modo interattivo\n"
#: g10/keygen.c:307
msgid ""
"Please select the algorithm to use:\n"
" (1) ElGamal is the suggested one.\n"
" (2) DSA can only be used for signatures.\n"
msgstr ""
"Per favore seleziona l'algoritmo da usare:\n"
" (1) ElGamal è quello consigliato.\n"
" (2) DSA può essere usato solo per firmare.\n"
#: g10/keygen.c:311
msgid " (3) RSA cannot be used in the U.S.\n"
msgstr " (3) RSA non può essere usato negli USA.\n"
#: g10/keygen.c:320
msgid "Your selection? (1,2,3) "
msgstr "La tua scelta? (1,2,3) "
#: g10/keygen.c:322
msgid "Your selection? (1,2) "
msgstr "La tua scelta? (1,2) "
#: g10/keygen.c:336
msgid "Sorry; DSA is not yet supported.\n"
msgstr "Mi spiace, DSA non è gestito.\n"
#: g10/keygen.c:349
msgid ""
"About to generate a new %s keypair.\n"
" minimum keysize is 768 bits\n"
" default keysize is 1024 bits\n"
" highest suggested keysize is 2048 bits\n"
msgstr ""
"Sto per generare una nuova coppia di chiavi %s.\n"
" la dimensione minima è 768 bit\n"
" la dimensione predefinita è 1024 bit\n"
" la dimensione massima suggerita è 2048 bit\n"
#: g10/keygen.c:357
msgid "What keysize do you want? (1024) "
msgstr "Di che dimensioni vuoi la chiave? (1024) "
#: g10/keygen.c:363
msgid "DSA does only allow keysizes from 512 to 1024\n"
msgstr "DSA permette solo chiavi di dimensioni da 512 a 1024\n"
#: g10/keygen.c:365
msgid "keysize too small; 768 is smallest value allowed.\n"
msgstr "le dimensioni della chiave sono troppo piccole; 768 è il\n"
"più piccolo valore permesso.\n"
#: g10/keygen.c:367
msgid ""
"Keysizes larger than 2048 are not suggested, because computations take "
"REALLY long!\n"
msgstr ""
"Chiavi di dimensioni maggiori di 2048 non sono consigliate, perchè i "
"calcoli sono VERAMENTE lunghi!\n"
#: g10/keygen.c:369
msgid "Are you sure, that you want this keysize? "
msgstr "Sei sicuro che vuoi una chiave di queste dimensioni? "
#: g10/keygen.c:373
msgid ""
"Okay, but keep in mind that your monitor and keyboard radiation is also very "
"vulnerable to attacks!\n"
msgstr "Va bene, ma ricordati che anche le radiazioni emesse dal tuo monitor "
"e dalla tua tastiera sono molto vulnerabili ad attacchi!\n"
#: g10/keygen.c:383
msgid "Requested keysize is %u bits\n"
msgstr "Le dimensioni della chiave richieste sono %u bit\n"
#: g10/keygen.c:386 g10/keygen.c:390
msgid "rounded up to %u bits\n"
msgstr "arrotondate a %u bit"
#: g10/keygen.c:397
msgid ""
"\n"
"You need a User-ID to identify your key; the software constructs the user "
"id\n"
"from Real Name, Comment and Email Address in this form:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n"
"\n"
msgstr ""
"\n"
"Ti serve un User ID per identificare la tua chiave; il software costruisce "
"l'user id a partire da Nome e Cognome, Commento e Indirizzo di Email "
"indicati in questo modulo:\n"
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n"
"\n"
#: g10/keygen.c:409
msgid "Real name: "
msgstr "Nome e Cognome: "
#: g10/keygen.c:413
msgid "Invalid character in name\n"
msgstr "Carattere non valido nel nome\n"
#: g10/keygen.c:415
msgid "Name may not start with a digit\n"
msgstr "Il nome non può iniziare con una cifra\n"
#: g10/keygen.c:417
msgid "Name must be at least 5 characters long\n"
msgstr "Il nome deve essere lungo almeno 5 caratteri\n"
#: g10/keygen.c:425
msgid "Email address: "
msgstr "Indirizzo di Email: "
#: g10/keygen.c:437
msgid "Not a valid email address\n"
msgstr "Non è un indirizzo di email valido\n"
#: g10/keygen.c:445
msgid "Comment: "
msgstr "Commento: "
#: g10/keygen.c:451
msgid "Invalid character in comment\n"
msgstr "Carattere non valido nel commento\n"
#: g10/keygen.c:471
msgid ""
"You selected this USER-ID:\n"
" \"%s\"\n"
"\n"
msgstr ""
"Hai selezionato questo User Id:\n"
" \"%s\"\n"
"\n"
#: g10/keygen.c:473
msgid "Edit (N)ame, (C)omment, (E)mail or (O)kay? "
msgstr "Modifica (N)ome, (C)ommento, (E)mail oppure (O)kay? "
#: g10/keygen.c:505
msgid ""
"You need a Passphrase to protect your secret key.\n"
"\n"
msgstr ""
"Ti serve una passphrase per proteggere la tua chiave segreta.\n"
"\n"
#: g10/keygen.c:516
msgid ""
"You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n"
"\n"
msgstr ""
"Non hai specificato una passphrase - questa è probabilmente una *cattiva*\n"
"idea! Lo farò io comunque. Puoi cambiarla in ogni momento, usando questo\n"
"programma con l'opzione \"--change-passphrase\"\n"
"\n"
#: g10/keygen.c:522
msgid "passphrase not correctly repeated; try again.\n"
msgstr "passphrase non ripetuta correttamente; riprova.\n"
#: g10/keygen.c:539
msgid "writing public certificate to '%s'\n"
msgstr "scrittura del certificato pubblico in '%s'\n"
#: g10/keygen.c:540
msgid "writing secret certificate to '%s'\n"
msgstr "scrittura del certificato privato in '%s'\n"
#: g10/keygen.c:552
msgid ""
"We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (work in another window, move the mouse, utilize the\n"
"network and the disks) during the prime generation; this gives the random\n"
"number generator a better chance to gain enough entropy.\n"
msgstr ""
"Dobbiamo generare un mucchio di byte casuali. È una buona idea eseguire\n"
"qualche altra azione (lavorare in un'altra finestra, muovere il mouse, usare\n"
"la rete e i dischi) durante la generazione dei numeri primi; questo da al\n"
"generatore di numeri casuali una maggiore possibilità di raccogliere\n"
"abbastanza entropia.\n"
#: g10/keygen.c:627
msgid "public and secret key created and signed.\n"
msgstr "chiavi pubbliche e segrete create e firmate.\n"
#: g10/keygen.c:638
msgid "Key generation failed: %s\n"
msgstr "Generazione della chiave fallita: %s\n"

View File

@ -47,7 +47,7 @@ strusage( int level )
static void
i18n_init(void)
{
#ifdef HAVE_LIBINTL
#ifdef ENABLE_NLS
#ifdef HAVE_LC_MESSAGES
setlocale( LC_MESSAGES, "" );
#else

View File

@ -65,7 +65,7 @@ strusage( int level )
static void
i18n_init(void)
{
#ifdef HAVE_LIBINTL
#ifdef ENABLE_NLS
#ifdef HAVE_LC_MESSAGES
setlocale( LC_MESSAGES, "" );
#else

View File

@ -1,3 +1,7 @@
Thu Mar 19 11:29:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* strgutil.c (memistr): Add const to return and first arg.
Sat Mar 7 11:54:35 1998 Werner Koch (wk@isil.d.shuttle.de)
* miscutil.c (print_string): New arg delim; changed all callers.

View File

@ -71,6 +71,7 @@ g10_errstr( int err )
X(RENAME_FILE ,"File rename error")
X(DELETE_FILE ,"File delete error")
X(UNEXPECTED ,"Unexpected data")
X(TIME_CONFLICT ,"Timestamp conflict")
default: p = buf; sprintf(buf, "g10err=%d", err); break;
}

View File

@ -77,15 +77,15 @@ strlist_last( STRLIST node )
* substring in BUF or NULL if not found.
* Comparison is case-in-sensitive.
*/
char *
memistr( char *buf, size_t buflen, const char *sub )
const char *
memistr( const char *buf, size_t buflen, const char *sub )
{
const byte *t, *s ;
size_t n;
for( t=buf, n=buflen, s=sub ; n ; t++, n-- )
if( toupper(*t) == toupper(*s) ) {
for( buf=(char*)t++, buflen = n--, s++;
for( buf=t++, buflen = n--, s++;
n && toupper(*t) == toupper(*s); t++, s++, n-- )
;
if( !*s )