mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
partial DSA support
This commit is contained in:
parent
1b1a6d7e77
commit
a6a8f1e706
@ -1,3 +1,7 @@
|
||||
Wed Mar 4 10:32:40 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* configure.in (getrusage,gettimeofday): New tests.
|
||||
|
||||
Fri Feb 27 13:14:17 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* configure.in (--disable-m-guard): New.
|
||||
|
14
NEWS
14
NEWS
@ -1,3 +1,17 @@
|
||||
Noteworthy changes in version 0.2.12
|
||||
------------------------------------
|
||||
|
||||
* --delete-key checks that there is no secret key. The new
|
||||
option --delete-secret-key maybe used to delete a secret key.
|
||||
|
||||
* "-kv" now works as expected. Options "--list-{keys,sigs]"
|
||||
and "--check-sigs" are now working.
|
||||
|
||||
* New options "--verify" and "--decrypt" to better support integration
|
||||
into MUAs (partly done for Mutt).
|
||||
|
||||
* New option "--with-colons" to make parsing of key lists easier.
|
||||
|
||||
Noteworthy changes in version 0.2.11
|
||||
------------------------------------
|
||||
|
||||
|
11
README
11
README
@ -3,8 +3,6 @@
|
||||
-------------------------------
|
||||
|
||||
THIS IS ALPHA SOFTWARE, EXPECT BUGS AND UNIMPLEMENTED STUFF.
|
||||
IT MAY HAPPEN THAT SOME DATA FORMATS OR PROGRAMM OPTIONS
|
||||
CHANGE WITH THE NEXT VERSION.
|
||||
|
||||
On a Linux box (version 2.x.x, alpha or x86 CPU) it should
|
||||
work reliable. You may create your key on such a machine and
|
||||
@ -105,7 +103,7 @@
|
||||
8) Continue with step 4 if we did not find a prime in step 7.
|
||||
9) Find a generator for that prime.
|
||||
|
||||
You should make a revocation certificate in cases someone gets
|
||||
You should make a revocation certificate in case someone gets
|
||||
knowledge of your secret key or you forgot your passphrase:
|
||||
|
||||
gpg --gen-revoke your_user_id
|
||||
@ -208,12 +206,14 @@
|
||||
"234567C4"
|
||||
"0F34E556E"
|
||||
"01347A56A"
|
||||
"0xAB123456
|
||||
|
||||
* By a complete keyid:
|
||||
|
||||
"234AABBCC34567C4"
|
||||
"0F323456784E56EAB"
|
||||
"01AB3FED1347A5612"
|
||||
"0x234AABBCC34567C4"
|
||||
|
||||
* By a fingerprint (not yet implemented):
|
||||
|
||||
@ -280,11 +280,6 @@
|
||||
you are asked for the passphrase, so that GNUPG is able to look at the
|
||||
inner structure of a encrypted packet.
|
||||
|
||||
gpgm --quick-random
|
||||
|
||||
Do not use the stroing random generator but a faster one. This can be
|
||||
used to generate keys for tests; those are marked as insecure.
|
||||
|
||||
gpgm --list-trustdb
|
||||
|
||||
List the contents of the trustdb in a human readable format
|
||||
|
2
THANKS
2
THANKS
@ -1,4 +1,4 @@
|
||||
G10 has originally been written by Werner Koch. Other people contributed
|
||||
GNUPG has originally been written by Werner Koch. Other people contributed
|
||||
by reporting problems, suggesting various improvements or submitting actual
|
||||
code. Here is a list of these people. Help me keeping it complete and
|
||||
exempt of errors.
|
||||
|
11
TODO
11
TODO
@ -13,9 +13,7 @@
|
||||
* complete cipher/cast.c
|
||||
* complete cipher/dsa.c
|
||||
|
||||
* add g10 stuff to Mutt's pgpinvoke.c
|
||||
|
||||
* Burn the buffers used by fopen().
|
||||
* Burn the buffers used by fopen(), or use read(2).
|
||||
|
||||
* bug: g10/trustdb.c#build_sigrecs called to often by do_list_path
|
||||
and remove the bad kludge. Maybe we should put all sigs into the trustdb
|
||||
@ -34,4 +32,11 @@
|
||||
them to your key and because the user id which is signed by others has
|
||||
also be signed by you, all user-ids are bound together.
|
||||
|
||||
* 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.
|
||||
|
||||
|
@ -1,3 +1,18 @@
|
||||
Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* dsa.c, dsa.h: Removed some unused code.
|
||||
|
||||
Wed Mar 4 10:39:22 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* md.c (md_open): Add call to fast_random_poll.
|
||||
blowfish.c (blowfish_setkey): Ditto.
|
||||
|
||||
Tue Mar 3 13:32:54 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* rmd160.c (rmd160_mixblock): New.
|
||||
* random.c: Restructured to start with a new RNG implementation.
|
||||
* random.h: New.
|
||||
|
||||
Mon Mar 2 19:21:46 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* gost.c, gost.h: Removed because they did only conatin trash.
|
||||
|
@ -13,6 +13,7 @@ libcipher_a_SOURCES = blowfish.c \
|
||||
md5.c \
|
||||
md5.h \
|
||||
primegen.c \
|
||||
random.h \
|
||||
random.c \
|
||||
rmd.h \
|
||||
rmd160.c \
|
||||
|
@ -104,6 +104,7 @@ libcipher_a_SOURCES = blowfish.c \
|
||||
md5.c \
|
||||
md5.h \
|
||||
primegen.c \
|
||||
random.h \
|
||||
random.c \
|
||||
rmd.h \
|
||||
rmd160.c \
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "util.h"
|
||||
#include "types.h"
|
||||
#include "blowfish.h"
|
||||
#include "random.h"
|
||||
|
||||
/* precomputed S boxes */
|
||||
static const u32 ks0[256] = {
|
||||
@ -421,6 +422,8 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
|
||||
selftest();
|
||||
}
|
||||
|
||||
fast_random_poll();
|
||||
|
||||
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
|
||||
c->p[i] = ps[i];
|
||||
for(i=0; i < 256; i++ ) {
|
||||
|
197
cipher/dsa.c
197
cipher/dsa.c
@ -32,6 +32,7 @@ void
|
||||
dsa_free_public_key( DSA_public_key *pk )
|
||||
{
|
||||
mpi_free( pk->p ); pk->p = NULL;
|
||||
mpi_free( pk->q ); pk->q = NULL;
|
||||
mpi_free( pk->g ); pk->g = NULL;
|
||||
mpi_free( pk->y ); pk->y = NULL;
|
||||
}
|
||||
@ -40,121 +41,13 @@ void
|
||||
dsa_free_secret_key( DSA_secret_key *sk )
|
||||
{
|
||||
mpi_free( sk->p ); sk->p = NULL;
|
||||
mpi_free( sk->q ); sk->q = NULL;
|
||||
mpi_free( sk->g ); sk->g = NULL;
|
||||
mpi_free( sk->y ); sk->y = NULL;
|
||||
mpi_free( sk->x ); sk->x = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_keys( DSA_public_key *pk, DSA_secret_key *sk, unsigned nbits )
|
||||
{
|
||||
MPI test = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
|
||||
MPI out1_a = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
|
||||
MPI out1_b = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
|
||||
MPI out2 = mpi_alloc( nbits / BITS_PER_MPI_LIMB );
|
||||
|
||||
mpi_set_bytes( test, nbits, get_random_byte, 0 );
|
||||
|
||||
dsa_sign( out1_a, out1_b, test, sk );
|
||||
if( !dsa_verify( out1_a, out1_b, test, pk ) )
|
||||
log_fatal("DSA operation: sign, verify failed\n");
|
||||
|
||||
mpi_free( test );
|
||||
mpi_free( out1_a );
|
||||
mpi_free( out1_b );
|
||||
mpi_free( out2 );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* generate a random secret exponent k from prime p, so
|
||||
* that k is relatively prime to p-1
|
||||
*/
|
||||
static MPI
|
||||
gen_k( MPI p )
|
||||
{
|
||||
MPI k = mpi_alloc_secure( mpi_get_nlimbs(p) );
|
||||
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
|
||||
MPI p_1 = mpi_copy(p);
|
||||
unsigned nbits = mpi_get_nbits(p);
|
||||
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random k ");
|
||||
mpi_sub_ui( p_1, p, 1);
|
||||
for(;;) {
|
||||
if( DBG_CIPHER )
|
||||
fputc('.', stderr);
|
||||
mpi_set_bytes( k, nbits, get_random_byte, 1 );
|
||||
mpi_set_highbit( k, nbits-1 ); /* make sure it's high (really needed?) */
|
||||
if( mpi_cmp( k, p_1 ) >= 0 )
|
||||
continue; /* is not smaller than (p-1) */
|
||||
if( mpi_gcd( temp, k, p_1 ) )
|
||||
break; /* okay, k is relatively prime to (p-1) */
|
||||
}
|
||||
if( DBG_CIPHER )
|
||||
fputc('\n', stderr);
|
||||
mpi_free(p_1);
|
||||
mpi_free(temp);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Generate a key pair with a key of size NBITS
|
||||
* Returns: 2 structures filles with all needed values
|
||||
*/
|
||||
void
|
||||
dsa_generate( DSA_public_key *pk, DSA_secret_key *sk, unsigned nbits )
|
||||
{
|
||||
MPI p; /* the prime */
|
||||
MPI g;
|
||||
MPI x; /* the secret exponent */
|
||||
MPI y;
|
||||
|
||||
p = generate_public_prime( nbits );
|
||||
/* FIXME: check wether we shall assert that (p-1)/2 is also prime
|
||||
* Schneier votes against it
|
||||
*/
|
||||
g = mpi_alloc_set_ui(3);
|
||||
|
||||
/* select a random number */
|
||||
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
|
||||
if( DBG_CIPHER )
|
||||
log_debug("choosing a random x ");
|
||||
do {
|
||||
if( DBG_CIPHER )
|
||||
fputc('.', stderr);
|
||||
mpi_set_bytes( x, nbits, get_random_byte, 1 ); /* fixme: should be 2 */
|
||||
mpi_set_highbit( x, nbits-1 ); /* make sure it's high (needed?) */
|
||||
} while( mpi_cmp( x, p ) >= 0 ); /* x must be smaller than p */
|
||||
|
||||
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
|
||||
mpi_powm( y, g, x, p );
|
||||
|
||||
if( DBG_CIPHER ) {
|
||||
fputc('\n', stderr);
|
||||
log_mpidump("dsa p= ", p );
|
||||
log_mpidump("dsa g= ", g );
|
||||
log_mpidump("dsa y= ", y );
|
||||
log_mpidump("dsa x= ", x );
|
||||
}
|
||||
|
||||
|
||||
/* copy the stuff to the key structures */
|
||||
pk->p = mpi_copy(p);
|
||||
pk->g = mpi_copy(g);
|
||||
pk->y = mpi_copy(y);
|
||||
sk->p = p;
|
||||
sk->g = g;
|
||||
sk->y = y;
|
||||
sk->x = x;
|
||||
|
||||
/* now we can test our keys (this should never fail!) */
|
||||
test_keys( pk, sk, nbits - 64 );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Test wether the secret key is valid.
|
||||
* Returns: if this is a valid key.
|
||||
@ -174,72 +67,58 @@ dsa_check_secret_key( DSA_secret_key *sk )
|
||||
|
||||
|
||||
/****************
|
||||
* Make an Elgamal signature out of INPUT
|
||||
* Make a DSA signature out of INPUT
|
||||
*/
|
||||
|
||||
void
|
||||
dsa_sign(MPI a, MPI b, MPI input, DSA_secret_key *skey )
|
||||
dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey )
|
||||
{
|
||||
MPI k;
|
||||
MPI t = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
MPI inv = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
MPI p_1 = mpi_copy(skey->p);
|
||||
|
||||
/*
|
||||
* b = (t * inv) mod (p-1)
|
||||
* b = (t * inv(k,(p-1),(p-1)) mod (p-1)
|
||||
* b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
|
||||
*
|
||||
*/
|
||||
mpi_sub_ui(p_1, p_1, 1);
|
||||
k = gen_k( skey->p );
|
||||
mpi_powm( a, skey->g, k, skey->p );
|
||||
mpi_mul(t, skey->x, a );
|
||||
mpi_subm(t, input, t, p_1 );
|
||||
while( mpi_is_neg(t) )
|
||||
mpi_add(t, t, p_1);
|
||||
mpi_invm(inv, k, p_1 );
|
||||
mpi_mulm(b, t, inv, p_1 );
|
||||
|
||||
#if 0
|
||||
if( DBG_CIPHER ) {
|
||||
log_mpidump("dsa sign p= ", skey->p);
|
||||
log_mpidump("dsa sign g= ", skey->g);
|
||||
log_mpidump("dsa sign y= ", skey->y);
|
||||
log_mpidump("dsa sign x= ", skey->x);
|
||||
log_mpidump("dsa sign k= ", k);
|
||||
log_mpidump("dsa sign M= ", input);
|
||||
log_mpidump("dsa sign a= ", a);
|
||||
log_mpidump("dsa sign b= ", b);
|
||||
}
|
||||
#endif
|
||||
mpi_free(k);
|
||||
mpi_free(t);
|
||||
mpi_free(inv);
|
||||
mpi_free(p_1);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Returns true if the signature composed from A and B is valid.
|
||||
* Returns true if the signature composed from R and S is valid.
|
||||
*/
|
||||
int
|
||||
dsa_verify(MPI a, MPI b, MPI input, DSA_public_key *pkey )
|
||||
dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey )
|
||||
{
|
||||
int rc;
|
||||
MPI t1 = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
MPI t2 = mpi_alloc( mpi_get_nlimbs(a) );
|
||||
MPI w, u1, u2, v;
|
||||
MPI base[3];
|
||||
MPI exp[3];
|
||||
|
||||
mpi_powm( t1, pkey->y, a, pkey->p );
|
||||
mpi_powm( t2, a, b, pkey->p );
|
||||
mpi_mulm( t1, t1, t2, pkey->p );
|
||||
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
|
||||
return 0; /* assertion 0 < r < q failed */
|
||||
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
|
||||
return 0; /* assertion 0 < s < q failed */
|
||||
|
||||
mpi_powm( t2, pkey->g, input, pkey->p );
|
||||
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
|
||||
v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
|
||||
|
||||
rc = !mpi_cmp( t1, t2 );
|
||||
/* w = s^(-1) mod q */
|
||||
mpi_invm( w, s, pkey->q );
|
||||
|
||||
mpi_free(t1);
|
||||
mpi_free(t2);
|
||||
/* u1 = (input * w) mod q */
|
||||
mpi_mulm( u1, input, w, pkey->q );
|
||||
|
||||
/* u2 = r * w mod q */
|
||||
mpi_mulm( u2, r, w, pkey->q );
|
||||
|
||||
/* v = g^u1 * y^u2 mod p mod q */
|
||||
base[0] = pkey->g; exp[0] = u1;
|
||||
base[1] = pkey->y; exp[1] = u2;
|
||||
base[2] = NULL; exp[2] = NULL;
|
||||
mpi_mulpowm( v, base, exp, pkey->p );
|
||||
mpi_fdiv_r( v, v, pkey->q );
|
||||
|
||||
rc = !mpi_cmp( v, r );
|
||||
|
||||
mpi_free(w);
|
||||
mpi_free(u1);
|
||||
mpi_free(u2);
|
||||
mpi_free(v);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ void dsa_free_public_key( DSA_public_key *pk );
|
||||
void dsa_free_secret_key( DSA_secret_key *sk );
|
||||
void dsa_generate( DSA_public_key *pk, DSA_secret_key *sk, unsigned nbits );
|
||||
int dsa_check_secret_key( DSA_secret_key *sk );
|
||||
void dsa_sign(MPI a, MPI b, MPI input, DSA_secret_key *skey);
|
||||
int dsa_verify(MPI a, MPI b, MPI input, DSA_public_key *pkey);
|
||||
void dsa_sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
|
||||
int dsa_verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
|
||||
|
||||
#endif /*G10_DSA_H*/
|
||||
|
@ -42,6 +42,7 @@ md_open( int algo, int secure )
|
||||
hd->secure = secure;
|
||||
if( algo )
|
||||
md_enable( hd, algo );
|
||||
fast_random_poll();
|
||||
return hd;
|
||||
}
|
||||
|
||||
|
@ -174,6 +174,7 @@ check_pubkey_algo( int algo )
|
||||
{
|
||||
switch( algo ) {
|
||||
case PUBKEY_ALGO_ELGAMAL:
|
||||
case PUBKEY_ALGO_DSA:
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
case PUBKEY_ALGO_RSA:
|
||||
#endif
|
||||
|
253
cipher/random.c
253
cipher/random.c
@ -18,6 +18,17 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
|
||||
/****************
|
||||
* How it works:
|
||||
*
|
||||
* See Peter Gutmann's Paper: "Software Generation of Practically
|
||||
* Strong Random Numbers"
|
||||
*
|
||||
* fixme!
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -26,27 +37,88 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef HAVE_GETTIMEOFTIME
|
||||
#include <sys/times.h>
|
||||
#endif
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "util.h"
|
||||
#include "cipher.h"
|
||||
#include "random.h"
|
||||
#include "rmd.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
#define BLOCKLEN 64 /* hash this amount of bytes */
|
||||
#define DIGESTLEN 20 /* into a digest of this length (rmd160) */
|
||||
/* poolblocks is the number of digests which make up the pool
|
||||
* and poolsize must be a multiple of the digest length
|
||||
* to make the AND operations faster, the size should also be
|
||||
* a multiple of ulong
|
||||
*/
|
||||
#define POOLBLOCKS 30
|
||||
#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
|
||||
#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
|
||||
#error Please make sure that poolsize is a multiple of ulong
|
||||
#endif
|
||||
#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
|
||||
#if SIZEOF_UNSIGNED_LONG == 8
|
||||
#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
|
||||
#elif SIZEOF_UNSIGNED_LONG == 4
|
||||
#define ADD_VALUE 0xa5a5a5a5
|
||||
#else
|
||||
#error weird size for an unsigned long
|
||||
#endif
|
||||
|
||||
struct cache {
|
||||
int len;
|
||||
byte buffer[100]; /* fixme: should be allocated with m_alloc_secure()*/
|
||||
int size;
|
||||
byte *buffer;
|
||||
};
|
||||
|
||||
|
||||
static int is_initialized;
|
||||
static struct cache cache[3];
|
||||
#define MASK_LEVEL(a) do {if( a > 2 ) a = 2; else if( a < 0 ) a = 0; } while(0)
|
||||
static char *rndpool; /* allocated size is POOLSIZE+BLOCKLEN */
|
||||
static char *keypool; /* allocated size is POOLSIZE+BLOCKLEN */
|
||||
static size_t pool_readpos;
|
||||
static size_t pool_writepos;
|
||||
static int pool_filled;
|
||||
static int just_mixed;
|
||||
|
||||
|
||||
static void fill_buffer( byte *buffer, size_t length, int level );
|
||||
static int secure_alloc;
|
||||
static int quick_test;
|
||||
|
||||
|
||||
|
||||
static void read_pool( byte *buffer, size_t length, int level );
|
||||
static void read_dev_random( byte *buffer, size_t length, int level );
|
||||
|
||||
|
||||
static void
|
||||
initialize()
|
||||
{
|
||||
/* The data buffer is allocated somewhat larger, so that
|
||||
* we can use this extra space (which is allocated in secure memory)
|
||||
* as a temporary hash buffer */
|
||||
rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
|
||||
: m_alloc_clear(POOLSIZE+BLOCKLEN);
|
||||
keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN)
|
||||
: m_alloc_clear(POOLSIZE+BLOCKLEN);
|
||||
is_initialized = 1;
|
||||
}
|
||||
|
||||
void
|
||||
secure_random_alloc()
|
||||
{
|
||||
secure_alloc = 1;
|
||||
}
|
||||
|
||||
int
|
||||
quick_random_gen( int onoff )
|
||||
{
|
||||
@ -78,14 +150,174 @@ get_random_byte( int level )
|
||||
{
|
||||
MASK_LEVEL(level);
|
||||
if( !cache[level].len ) {
|
||||
fill_buffer(cache[level].buffer, DIM(cache[level].buffer), level );
|
||||
cache[level].len = DIM(cache[level].buffer);
|
||||
if( !is_initialized )
|
||||
initialize();
|
||||
if( !cache[level].buffer ) {
|
||||
cache[level].size = 100;
|
||||
cache[level].buffer = level && secure_alloc?
|
||||
m_alloc_secure( cache[level].size )
|
||||
: m_alloc( cache[level].size );
|
||||
}
|
||||
read_pool(cache[level].buffer, cache[level].size, level );
|
||||
cache[level].len = cache[level].size;
|
||||
}
|
||||
|
||||
return cache[level].buffer[--cache[level].len];
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Mix the pool
|
||||
*/
|
||||
static void
|
||||
mix_pool(byte *pool)
|
||||
{
|
||||
char *hashbuf = pool + POOLSIZE;
|
||||
char *p, *pend;
|
||||
int i, n;
|
||||
RMD160_CONTEXT md;
|
||||
|
||||
rmd160_init( &md );
|
||||
#if DIGESTLEN != 20
|
||||
#error must have a digest length of 20 for ripe-md-160
|
||||
#endif
|
||||
/* loop over the pool */
|
||||
pend = pool + POOLSIZE;
|
||||
memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
|
||||
memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
|
||||
rmd160_mixblock( &md, hashbuf);
|
||||
memcpy(pool, hashbuf, 20 );
|
||||
|
||||
p = pool;
|
||||
for( n=1; n < POOLBLOCKS; n++ ) {
|
||||
memcpy(hashbuf, p, DIGESTLEN );
|
||||
|
||||
p += DIGESTLEN;
|
||||
if( p+DIGESTLEN+BLOCKLEN < pend )
|
||||
memcpy(hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
|
||||
else {
|
||||
char *pp = p+DIGESTLEN;
|
||||
for(i=DIGESTLEN; i < BLOCKLEN; i++ ) {
|
||||
if( pp >= pend )
|
||||
pp = pool;
|
||||
hashbuf[i] = *pp++;
|
||||
}
|
||||
}
|
||||
|
||||
rmd160_mixblock( &md, hashbuf);
|
||||
memcpy(p, hashbuf, 20 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_pool( byte *buffer, size_t length, int level )
|
||||
{
|
||||
int i;
|
||||
ulong *sp, *dp;
|
||||
|
||||
if( length >= POOLSIZE )
|
||||
BUG(); /* not allowed */
|
||||
if( !level ) { /* read simple random bytes */
|
||||
read_dev_random( buffer, length, level );
|
||||
return;
|
||||
}
|
||||
|
||||
/* always do a random poll if we need strong numbers */
|
||||
if( pool_filled && level == 2 )
|
||||
random_poll();
|
||||
/* make sure the pool is filled */
|
||||
while( !pool_filled )
|
||||
random_poll();
|
||||
/* do always a fast random poll */
|
||||
fast_random_poll();
|
||||
|
||||
/* mix the pool (if add_randomness() didn't it) */
|
||||
if( !just_mixed )
|
||||
mix_pool(rndpool);
|
||||
|
||||
/* create a new pool */
|
||||
for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
|
||||
i < POOLWORDS; i++, dp++, sp++ )
|
||||
*dp = *sp + ADD_VALUE;
|
||||
/* and mix both pools */
|
||||
mix_pool(rndpool);
|
||||
mix_pool(keypool);
|
||||
/* read the required data
|
||||
* we use a readpoiter to read from a different postion each
|
||||
* time */
|
||||
while( length-- ) {
|
||||
*buffer++ = keypool[pool_readpos++];
|
||||
if( pool_readpos >= POOLSIZE )
|
||||
pool_readpos = 0;
|
||||
}
|
||||
/* and clear the keypool */
|
||||
memset( keypool, 0, POOLSIZE );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Add LENGTH bytes of randomness from buffer to the pool.
|
||||
* source may be used to specify the randomeness source.
|
||||
*/
|
||||
void
|
||||
add_randomness( const void *buffer, size_t length, int source )
|
||||
{
|
||||
if( !is_initialized )
|
||||
initialize();
|
||||
while( length-- ) {
|
||||
rndpool[pool_writepos++] = *((byte*)buffer)++;
|
||||
if( pool_writepos >= POOLSIZE ) {
|
||||
pool_filled = 1;
|
||||
pool_writepos = 0;
|
||||
mix_pool(rndpool);
|
||||
just_mixed = !length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************
|
||||
* FIXME: move these functions to rand_unix.c
|
||||
*/
|
||||
|
||||
void
|
||||
random_poll()
|
||||
{
|
||||
char buf[POOLSIZE/5];
|
||||
read_dev_random( buf, POOLSIZE/5, 1 ); /* read /dev/urandom */
|
||||
add_randomness( buf, POOLSIZE/5, 2);
|
||||
memset( buf, 0, POOLSIZE/5);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fast_random_poll()
|
||||
{
|
||||
#ifdef HAVE_GETTIMEOFTIME
|
||||
{ struct timeval tv;
|
||||
if( gettimeofday( &tv, NULL ) )
|
||||
BUG();
|
||||
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
|
||||
add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
|
||||
}
|
||||
#else /* use times */
|
||||
{ struct tms buf;
|
||||
times( &buf );
|
||||
add_randomness( &buf, sizeof buf, 1 );
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
{ struct rusage buf;
|
||||
if( getrusage( RUSAGE_SELF, &buf ) )
|
||||
BUG();
|
||||
add_randomness( &buf, sizeof buf, 1 );
|
||||
memset( &buf, 0, sizeof buf );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_DEV_RANDOM
|
||||
|
||||
@ -111,7 +343,7 @@ open_device( const char *name, int minor )
|
||||
|
||||
|
||||
static void
|
||||
fill_buffer( byte *buffer, size_t length, int level )
|
||||
read_dev_random( byte *buffer, size_t length, int level )
|
||||
{
|
||||
static int fd_urandom = -1;
|
||||
static int fd_random = -1;
|
||||
@ -125,6 +357,9 @@ fill_buffer( byte *buffer, size_t length, int level )
|
||||
fd = fd_random;
|
||||
}
|
||||
else {
|
||||
/* fixme: we should use a simpler one for level 0,
|
||||
* because reading from /dev/urandom removes entropy
|
||||
* and the next read on /dev/random may have to wait */
|
||||
if( fd_urandom == -1 )
|
||||
fd_urandom = open_device( "/dev/urandom", 9 );
|
||||
fd = fd_urandom;
|
||||
@ -154,7 +389,7 @@ fill_buffer( byte *buffer, size_t length, int level )
|
||||
continue;
|
||||
}
|
||||
|
||||
assert( length < 200 );
|
||||
assert( length < 500 );
|
||||
do {
|
||||
n = read(fd, buffer, length );
|
||||
if( n >= 0 && n > length ) {
|
||||
@ -178,7 +413,7 @@ fill_buffer( byte *buffer, size_t length, int level )
|
||||
#endif
|
||||
|
||||
static void
|
||||
fill_buffer( byte *buffer, size_t length, int level )
|
||||
read_dev_random( byte *buffer, size_t length, int level )
|
||||
{
|
||||
static int initialized=0;
|
||||
|
||||
|
39
cipher/random.h
Normal file
39
cipher/random.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* random.h - random functions
|
||||
* 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
|
||||
*/
|
||||
#ifndef G10_RANDOM_H
|
||||
#define G10_RANDOM_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*-- random.c --*/
|
||||
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 );
|
||||
void add_randomness( const void *buffer, size_t length, int source );
|
||||
|
||||
|
||||
/*-- the next two functions are implemented by all the system
|
||||
specific source files rand_xxxx.s --*/
|
||||
void random_poll(void);
|
||||
void fast_random_poll(void);
|
||||
|
||||
|
||||
#endif /*G10_RANDOM_H*/
|
@ -33,6 +33,7 @@ typedef struct {
|
||||
void rmd160_init( RMD160_CONTEXT *c );
|
||||
void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen);
|
||||
void rmd160_final(RMD160_CONTEXT *hd);
|
||||
void rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer );
|
||||
#define rmd160_read(h) ( (h)->buf )
|
||||
|
||||
#endif /*G10_RMD_H*/
|
||||
|
@ -300,6 +300,27 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Apply the rmd160 transform function on the buffer which must have
|
||||
* a length 64 bytes. Do not use this function together with the
|
||||
* other functions, use rmd160_init to initialize intzernal variables.
|
||||
* Returns: 16 bytes in buffer with the mixed contentes of buffer.
|
||||
*/
|
||||
void
|
||||
rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer )
|
||||
{
|
||||
char *p = buffer;
|
||||
transform( hd, buffer );
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
X(0);
|
||||
X(1);
|
||||
X(2);
|
||||
X(3);
|
||||
X(4);
|
||||
#undef X
|
||||
}
|
||||
|
||||
|
||||
/* The routine terminates the computation
|
||||
*/
|
||||
|
||||
|
@ -142,6 +142,12 @@
|
||||
/* Define if you have the getpagesize function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define if you have the getrusage function. */
|
||||
#undef HAVE_GETRUSAGE
|
||||
|
||||
/* Define if you have the gettimeofday function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define if you have the mlock function. */
|
||||
#undef HAVE_MLOCK
|
||||
|
||||
|
@ -133,6 +133,7 @@ fi
|
||||
dnl Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul mlock mmap)
|
||||
AC_CHECK_FUNCS(gettimeofday getrusage)
|
||||
|
||||
|
||||
|
||||
|
71
doc/gpg.1pod
71
doc/gpg.1pod
@ -32,13 +32,30 @@ B<-c>, B<--symmetric>
|
||||
This command asks for a passphrase.
|
||||
|
||||
B<--store>
|
||||
store only (make a RFC1991 packet).
|
||||
store only (make a simple RFC1991 packet).
|
||||
|
||||
B<-d>, B<--decrypt>
|
||||
Decrypt data. This is the default operation for data
|
||||
files.
|
||||
B<--decrypt> [I<file>]
|
||||
Decrypt file (or stdin if no file is specified) and
|
||||
write it to stdout (or the file specified with
|
||||
B<--output>). If the decrypted file is signed, the
|
||||
signature is also verified. This command differs
|
||||
from the default operation, as it never write to the
|
||||
filename which is included in the file and that it
|
||||
rejects files which don't begin with an encrypted
|
||||
message.
|
||||
|
||||
B<-k> [I<keyring>]
|
||||
B<--verify> [[I<sigfile>] {I<signed-files>}]
|
||||
Assume that I<filename> is a signature and verify it
|
||||
without generating any output. With no arguments,
|
||||
the signature packet is read from stdin (it may be a
|
||||
detached signature when not used in batch mode). If
|
||||
only a sigfile is given, is maybe a complete signature
|
||||
or a detached signature in which case the signed stuff
|
||||
is expected from stdin. With more than 1 argument, the
|
||||
first should be a detached signature and the remaining
|
||||
files are the signed stuff.
|
||||
|
||||
B<-k> [I<username>] [I<keyring>]
|
||||
Kludge to be somewhat compatibe to PGP.
|
||||
Without arguments, all public key-rings are listed,
|
||||
with one argument, only I<keyring> is listed.
|
||||
@ -50,15 +67,21 @@ B<-k> [I<keyring>]
|
||||
B<-kvc> List fingerprints
|
||||
B<-kvvc> List fingerprints and signatures
|
||||
|
||||
B<--list-keys>
|
||||
List all keys in all public key-rings and check the
|
||||
signatures.
|
||||
B<--list-keys> [I<names>]
|
||||
List all keys from the default public keyring or just the ones
|
||||
given on the commandline.
|
||||
|
||||
B<--check-keys>
|
||||
Check signatures on a key in the keyring
|
||||
B<--list-sigs> [I<names>]
|
||||
Same as B<--list-keys>, but the signatures are listed too.
|
||||
|
||||
B<--fingerprint>
|
||||
Show the fingerprints
|
||||
B<--check-sigs> [I<names>]
|
||||
Same as B<--list-sigs>, but the signatures are verified.
|
||||
|
||||
B<--fingerprint> [I<names>]
|
||||
List all keys with their fingerprints. This is the
|
||||
same output as B<list-keys> but with the additonal output
|
||||
of a line with the fingerprint. May also be combined
|
||||
with B<--list-sigs> or B<--check-sigs>.
|
||||
|
||||
B<--list-packets>
|
||||
List only the sequence of packets. This is mainly
|
||||
@ -84,7 +107,10 @@ B<--sign-key> I<name>
|
||||
B<--delete-key>
|
||||
Remove key from the public keyring
|
||||
|
||||
B<--edit-sig>
|
||||
B<--delete-secret-key>
|
||||
Remove key from the secret and public keyring
|
||||
|
||||
B<--edit-key>
|
||||
Edit/remove a key signature.
|
||||
|
||||
B<--change-passphrase>
|
||||
@ -124,9 +150,13 @@ B<-o> I<file>, B<--output> I<file>
|
||||
|
||||
B<-u> I<name>, B<--local-user> I<name>
|
||||
Use I<name> as the user-id to sign.
|
||||
This option is silently ignored for the list commands,
|
||||
so that it can be used in an options file.
|
||||
|
||||
B<-r> I<name>, B<--remote-user> I<name>
|
||||
Use I<name> as the user-id for encryption.
|
||||
Use I<name> as the user-id for encryption.
|
||||
This option is silently ignored for the list commands,
|
||||
so that it can be used in an options file.
|
||||
|
||||
B<-v>, B<--verbose>
|
||||
Give more informations during processing. If used
|
||||
@ -181,7 +211,7 @@ B<--options> I<file>
|
||||
(see B<--homedir>). This option is ignored when used
|
||||
in an options file.
|
||||
|
||||
B<no-options>
|
||||
B<--no-options>
|
||||
Shortcut for B<--options> I</dev/null>. This option is
|
||||
detected before an attempt to open an option file.
|
||||
|
||||
@ -227,17 +257,17 @@ B<--passphrase-fd> I<n>
|
||||
can only be used if only one passphrase is supplied.
|
||||
B<Don't use this option if you can avoid it>
|
||||
|
||||
B<no-verbose>
|
||||
B<--no-verbose>
|
||||
Reset verbose level to 0.
|
||||
|
||||
B<no-greeting>
|
||||
B<--no-greeting>
|
||||
Suppress the initial copyright message but do not
|
||||
enter batch mode.
|
||||
|
||||
B<no-armor>
|
||||
B<--no-armor>
|
||||
Assume the input data is not in ASCCI armored format.
|
||||
|
||||
B<no-default-keyring>
|
||||
B<--no-default-keyring>
|
||||
Do not add the default key-rings to the list of
|
||||
key-rings.
|
||||
|
||||
@ -245,6 +275,9 @@ B<--version>
|
||||
Print version information along with a list
|
||||
of supported algorithms.
|
||||
|
||||
B<--with-colons>
|
||||
Print key listings delimited by colons.
|
||||
|
||||
B<--warranty>
|
||||
Print warranty information.
|
||||
|
||||
|
@ -1,3 +1,49 @@
|
||||
Mon Mar 9 12:43:42 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* dsa.c: New
|
||||
* packet.h, free-packet.c, parse-packet.c : Add support for DSA
|
||||
* sig-check.c, getkey.c, keyid.c, ringedit.c: Ditto.
|
||||
* seckey-cert.c: Ditto.
|
||||
|
||||
* packet.h : Moved .digest_algo of signature packets to outer
|
||||
structure. Changed all references
|
||||
|
||||
Sun Mar 8 13:06:42 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* openfile.c : Support for stdout filename "-".
|
||||
|
||||
* mainproc.c (check_sig_and_print): Enhanced status output:
|
||||
* status.c (write_status_text): New.
|
||||
|
||||
Fri Mar 6 16:10:54 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* kbnode.c (clone_kbnode): Fixed private_flag.
|
||||
|
||||
* mainproc.c (list_node): Output of string "Revoked" as user-id.
|
||||
|
||||
Fri Mar 6 14:26:39 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* g10.c (main): Add userids to "-kv" and cleaned up this stuff.
|
||||
|
||||
Fri Mar 6 12:45:58 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* g10.c (main): Changed semantics of the list-... commands
|
||||
and added a new one. Removed option "-d"
|
||||
|
||||
* decrypt.c: New.
|
||||
|
||||
* trustdb.c (init_trustdb): Autocreate directory only if it ends
|
||||
in "/.gnupg".
|
||||
|
||||
Thu Mar 5 12:12:11 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* mainproc.c (do_proc_packets): New. Common part of proc_packet.
|
||||
(proc_signature_packets): special version to handle signature data.
|
||||
* verify.c: New.
|
||||
* g10.c (aVerify): New.
|
||||
* plaintext.c (hash_datafiles): New.
|
||||
* compress.c (handle_compressed): Add callback arg, changed caller.
|
||||
|
||||
Thu Mar 5 10:20:06 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* g10.c: Is nom the common source for gpg and gpgm
|
||||
|
@ -26,6 +26,7 @@ common_source = \
|
||||
textfilter.c \
|
||||
cipher.c \
|
||||
elg.c \
|
||||
dsa.c \
|
||||
rsa.c \
|
||||
options.h \
|
||||
openfile.c \
|
||||
@ -48,16 +49,18 @@ common_source = \
|
||||
encr-data.c \
|
||||
encode.c \
|
||||
revoke.c \
|
||||
keylist.c \
|
||||
sig-check.c
|
||||
|
||||
gpg_SOURCES = g10.c \
|
||||
$(common_source) \
|
||||
verify.c \
|
||||
decrypt.c \
|
||||
keygen.c
|
||||
|
||||
|
||||
gpgm_SOURCES = g10maint.c \
|
||||
dearmor.c \
|
||||
keylist.c \
|
||||
$(common_source)
|
||||
|
||||
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
|
||||
|
@ -118,6 +118,7 @@ common_source = \
|
||||
textfilter.c \
|
||||
cipher.c \
|
||||
elg.c \
|
||||
dsa.c \
|
||||
rsa.c \
|
||||
options.h \
|
||||
openfile.c \
|
||||
@ -140,15 +141,17 @@ common_source = \
|
||||
encr-data.c \
|
||||
encode.c \
|
||||
revoke.c \
|
||||
keylist.c \
|
||||
sig-check.c
|
||||
|
||||
gpg_SOURCES = g10.c \
|
||||
$(common_source) \
|
||||
verify.c \
|
||||
decrypt.c \
|
||||
keygen.c
|
||||
|
||||
gpgm_SOURCES = g10maint.c \
|
||||
dearmor.c \
|
||||
keylist.c \
|
||||
$(common_source)
|
||||
|
||||
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
|
||||
@ -164,20 +167,20 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
gpg_OBJECTS = g10.o build-packet.o compress.o 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 rsa.o openfile.o keyid.o trustdb.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 sig-check.o keygen.o
|
||||
encode.o revoke.o keylist.o sig-check.o verify.o decrypt.o keygen.o
|
||||
gpg_LDADD = $(LDADD)
|
||||
gpg_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
|
||||
../util/libutil.a
|
||||
gpg_LDFLAGS =
|
||||
gpgm_OBJECTS = g10maint.o dearmor.o keylist.o build-packet.o compress.o \
|
||||
gpgm_OBJECTS = g10maint.o dearmor.o build-packet.o compress.o \
|
||||
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 rsa.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 sig-check.o
|
||||
plaintext.o encr-data.o encode.o revoke.o keylist.o sig-check.o
|
||||
gpgm_LDADD = $(LDADD)
|
||||
gpgm_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
|
||||
../util/libutil.a
|
||||
@ -193,16 +196,16 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
TAR = tar
|
||||
GZIP = --best
|
||||
DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \
|
||||
.deps/comment.P .deps/compress.P .deps/dearmor.P .deps/elg.P \
|
||||
.deps/encode.P .deps/encr-data.P .deps/export.P .deps/free-packet.P \
|
||||
.deps/g10.P .deps/g10maint .deps/g10maint.P .deps/getkey.P \
|
||||
.deps/import.P .deps/kbnode.P .deps/keygen.P .deps/keyid.P \
|
||||
.deps/keylist.P .deps/mainproc.P .deps/mdfilter.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/comment.P .deps/compress.P .deps/dearmor.P .deps/decrypt.P \
|
||||
.deps/dsa.P .deps/elg.P .deps/encode.P .deps/encr-data.P .deps/export.P \
|
||||
.deps/free-packet.P .deps/g10.P .deps/g10maint .deps/g10maint.P \
|
||||
.deps/getkey.P .deps/import.P .deps/kbnode.P .deps/keygen.P \
|
||||
.deps/keyid.P .deps/keylist.P .deps/mainproc.P .deps/mdfilter.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
|
||||
SOURCES = $(gpg_SOURCES) $(gpgm_SOURCES)
|
||||
OBJECTS = $(gpg_OBJECTS) $(gpgm_OBJECTS)
|
||||
|
||||
|
10
g10/armor.c
10
g10/armor.c
@ -322,7 +322,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
buf[--n] = 0;
|
||||
if( opt.verbose ) {
|
||||
log_info("armor header: ");
|
||||
print_string( stderr, buf, n );
|
||||
print_string( stderr, buf, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
if( clearsig && !parse_hash_header( buf ) ) {
|
||||
@ -348,7 +348,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
}
|
||||
else {
|
||||
log_error("invalid armor header: ");
|
||||
print_string( stderr, buf, n );
|
||||
print_string( stderr, buf, n, 0 );
|
||||
putc('\n', stderr);
|
||||
state = fhdrERROR;
|
||||
}
|
||||
@ -357,7 +357,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
if( strchr( buf, ':') ) { /* buffer to short, but this is okay*/
|
||||
if( opt.verbose ) {
|
||||
log_info("armor header: ");
|
||||
print_string( stderr, buf, n );
|
||||
print_string( stderr, buf, n, 0 );
|
||||
fputs("[...]\n", stderr); /* indicate it is truncated */
|
||||
}
|
||||
state = fhdrSKIPHeader; /* skip rest of line */
|
||||
@ -462,7 +462,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
}
|
||||
else {
|
||||
log_error("invalid dash escaped line: ");
|
||||
print_string( stderr, buf, n );
|
||||
print_string( stderr, buf, n, 0 );
|
||||
putc('\n', stderr);
|
||||
state = fhdrERROR;
|
||||
}
|
||||
@ -531,7 +531,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
|
||||
case fhdrERRORShow:
|
||||
log_error("invalid clear text header: ");
|
||||
print_string( stderr, buf, n );
|
||||
print_string( stderr, buf, n, 0 );
|
||||
putc('\n', stderr);
|
||||
state = fhdrERROR;
|
||||
break;
|
||||
|
@ -175,13 +175,20 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
|
||||
else
|
||||
iobuf_put( a, pkc->version );
|
||||
write_32(a, pkc->timestamp );
|
||||
write_16(a, pkc->valid_days );
|
||||
if( pkc->version < 4 )
|
||||
write_16(a, pkc->valid_days );
|
||||
iobuf_put(a, pkc->pubkey_algo );
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
mpi_write(a, pkc->d.elg.p );
|
||||
mpi_write(a, pkc->d.elg.g );
|
||||
mpi_write(a, pkc->d.elg.y );
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mpi_write(a, pkc->d.dsa.p );
|
||||
mpi_write(a, pkc->d.dsa.q );
|
||||
mpi_write(a, pkc->d.dsa.g );
|
||||
mpi_write(a, pkc->d.dsa.y );
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
mpi_write(a, pkc->d.rsa.rsa_n );
|
||||
mpi_write(a, pkc->d.rsa.rsa_e );
|
||||
@ -253,7 +260,8 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
|
||||
else
|
||||
iobuf_put( a, skc->version );
|
||||
write_32(a, skc->timestamp );
|
||||
write_16(a, skc->valid_days );
|
||||
if( skc->version < 4 )
|
||||
write_16(a, skc->valid_days );
|
||||
iobuf_put(a, skc->pubkey_algo );
|
||||
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
mpi_write(a, skc->d.elg.p );
|
||||
@ -416,24 +424,35 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||
int rc = 0;
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
write_version( a, ctb );
|
||||
iobuf_put(a, 5 ); /* constant */
|
||||
if( !sig->version )
|
||||
iobuf_put( a, 3 );
|
||||
else
|
||||
iobuf_put( a, sig->version );
|
||||
if( sig->version < 4 )
|
||||
iobuf_put(a, 5 ); /* constant */
|
||||
iobuf_put(a, sig->sig_class );
|
||||
write_32(a, sig->timestamp );
|
||||
write_32(a, sig->keyid[0] );
|
||||
write_32(a, sig->keyid[1] );
|
||||
if( sig->version < 4 ) {
|
||||
write_32(a, sig->timestamp );
|
||||
write_32(a, sig->keyid[0] );
|
||||
write_32(a, sig->keyid[1] );
|
||||
}
|
||||
iobuf_put(a, sig->pubkey_algo );
|
||||
iobuf_put(a, sig->digest_algo );
|
||||
if( sig->version >= 4 ) {
|
||||
/* fixme: write v4 subpackets here */
|
||||
log_error("WARNING: note writing of v4 subpackets is not implemented\n");
|
||||
}
|
||||
iobuf_put(a, sig->digest_start[0] );
|
||||
iobuf_put(a, sig->digest_start[1] );
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
iobuf_put(a, sig->d.elg.digest_algo );
|
||||
iobuf_put(a, sig->d.elg.digest_start[0] );
|
||||
iobuf_put(a, sig->d.elg.digest_start[1] );
|
||||
mpi_write(a, sig->d.elg.a );
|
||||
mpi_write(a, sig->d.elg.b );
|
||||
}
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mpi_write(a, sig->d.dsa.r );
|
||||
mpi_write(a, sig->d.dsa.s );
|
||||
}
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
iobuf_put(a, sig->d.rsa.digest_algo );
|
||||
iobuf_put(a, sig->d.rsa.digest_start[0] );
|
||||
iobuf_put(a, sig->d.rsa.digest_start[1] );
|
||||
mpi_write(a, sig->d.rsa.rsa_integer );
|
||||
}
|
||||
else {
|
||||
|
@ -230,9 +230,11 @@ compress_filter( void *opaque, int control,
|
||||
* Handle a compressed packet
|
||||
*/
|
||||
int
|
||||
handle_compressed( PKT_compressed *cd )
|
||||
handle_compressed( PKT_compressed *cd,
|
||||
int (*callback)(IOBUF, void *), void *passthru )
|
||||
{
|
||||
compress_filter_context_t cfx;
|
||||
int rc;
|
||||
|
||||
memset( &cfx, 0, sizeof cfx );
|
||||
if( cd->algorithm == 1 )
|
||||
@ -241,7 +243,10 @@ handle_compressed( PKT_compressed *cd )
|
||||
return G10ERR_COMPR_ALGO;
|
||||
|
||||
iobuf_push_filter( cd->buf, compress_filter, &cfx );
|
||||
proc_packets(cd->buf);
|
||||
if( callback )
|
||||
rc = callback(cd->buf, passthru );
|
||||
else
|
||||
rc = proc_packets(cd->buf);
|
||||
iobuf_pop_filter( cd->buf, compress_filter, &cfx );
|
||||
#if 0
|
||||
if( cd->len )
|
||||
@ -250,6 +255,6 @@ handle_compressed( PKT_compressed *cd )
|
||||
iobuf_clear_eof( cd->buf );
|
||||
#endif
|
||||
cd->buf = NULL;
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
82
g10/decrypt.c
Normal file
82
g10/decrypt.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* verify.c - verify signed data
|
||||
* 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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Assume that the input is an encrypted message and decrypt
|
||||
* (and if signed, verify the signature) it.
|
||||
* This command differs from the default operation, as it never
|
||||
* write to the filename which is included in the file and that it
|
||||
* rejects files which don't begin with an encrypted message.
|
||||
*/
|
||||
|
||||
int
|
||||
decrypt_message( const char *filename )
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
int rc;
|
||||
int no_out=0;
|
||||
|
||||
/* open the message file */
|
||||
fp = iobuf_open(filename);
|
||||
if( !fp ) {
|
||||
log_error(_("can't open '%s'\n"), print_fname_stdin(filename));
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
if( !opt.no_armor ) {
|
||||
if( use_armor_filter( fp ) ) {
|
||||
memset( &afx, 0, sizeof afx);
|
||||
iobuf_push_filter( fp, armor_filter, &afx );
|
||||
}
|
||||
}
|
||||
|
||||
if( !opt.outfile ) {
|
||||
no_out = 1;
|
||||
opt.outfile = "-";
|
||||
}
|
||||
rc = proc_encryption_packets( fp );
|
||||
if( no_out )
|
||||
opt.outfile = NULL;
|
||||
iobuf_close(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
71
g10/dsa.c
Normal file
71
g10/dsa.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* dsa.c
|
||||
* 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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
void
|
||||
g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
MD_HANDLE md, int digest_algo )
|
||||
{
|
||||
DSA_secret_key skey;
|
||||
MPI frame;
|
||||
byte *dp;
|
||||
|
||||
assert( sig->pubkey_algo == PUBKEY_ALGO_DSA );
|
||||
if( !digest_algo )
|
||||
digest_algo = md_get_algo(md);
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
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));
|
||||
skey.p = skc->d.elg.p;
|
||||
skey.g = skc->d.elg.g;
|
||||
skey.y = skc->d.elg.y;
|
||||
skey.x = skc->d.elg.x;
|
||||
dsa_sign( sig->d.dsa.r, sig->d.dsa.s, frame, &skey);
|
||||
memset( &skey, 0, sizeof skey );
|
||||
mpi_free(frame);
|
||||
if( opt.verbose ) {
|
||||
char *ustr = get_user_id_string( sig->keyid );
|
||||
log_info("DSA signature from: %s\n", ustr );
|
||||
m_free(ustr);
|
||||
}
|
||||
}
|
||||
|
@ -79,9 +79,9 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->d.elg.digest_algo = digest_algo;
|
||||
sig->d.elg.digest_start[0] = dp[0];
|
||||
sig->d.elg.digest_start[1] = dp[1];
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
|
||||
sig->d.elg.b = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
|
||||
frame = encode_md_value( md, mpi_get_nbits(skc->d.elg.p));
|
||||
|
@ -45,31 +45,41 @@ free_pubkey_enc( PKT_pubkey_enc *enc )
|
||||
}
|
||||
|
||||
void
|
||||
free_seckey_enc( PKT_signature *enc )
|
||||
free_seckey_enc( PKT_signature *sig )
|
||||
{
|
||||
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
mpi_free( enc->d.elg.a );
|
||||
mpi_free( enc->d.elg.b );
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
mpi_free( sig->d.elg.a );
|
||||
mpi_free( sig->d.elg.b );
|
||||
}
|
||||
else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
mpi_free( enc->d.rsa.rsa_integer );
|
||||
m_free(enc);
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mpi_free( sig->d.dsa.r );
|
||||
mpi_free( sig->d.dsa.s );
|
||||
}
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
mpi_free( sig->d.rsa.rsa_integer );
|
||||
m_free(sig->hashed_data);
|
||||
m_free(sig->unhashed_data);
|
||||
m_free(sig);
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Return the digest algorith from the signature packet.
|
||||
* Return the digest algorithm from the signature packet.
|
||||
* We need this function because the digeste algo depends on the
|
||||
* used pubkey algorithm.
|
||||
*/
|
||||
int
|
||||
digest_algo_from_sig( PKT_signature *sig )
|
||||
{
|
||||
#if 0 /* not used anymore */
|
||||
switch( sig->pubkey_algo ) {
|
||||
case PUBKEY_ALGO_ELGAMAL: return sig->d.elg.digest_algo;
|
||||
case PUBKEY_ALGO_DSA: return sig->d.dsa.digest_algo;
|
||||
case PUBKEY_ALGO_RSA: return sig->d.rsa.digest_algo;
|
||||
default: return 0;
|
||||
}
|
||||
#endif
|
||||
return sig->digest_algo;
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +93,12 @@ release_public_cert_parts( PKT_public_cert *cert )
|
||||
mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
|
||||
mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
|
||||
}
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
|
||||
mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
|
||||
mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
|
||||
mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
|
||||
}
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL;
|
||||
mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL;
|
||||
@ -107,6 +123,12 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
|
||||
d->d.elg.g = mpi_copy( s->d.elg.g );
|
||||
d->d.elg.y = mpi_copy( s->d.elg.y );
|
||||
}
|
||||
else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
d->d.dsa.p = mpi_copy( s->d.dsa.p );
|
||||
d->d.dsa.q = mpi_copy( s->d.dsa.q );
|
||||
d->d.dsa.g = mpi_copy( s->d.dsa.g );
|
||||
d->d.dsa.y = mpi_copy( s->d.dsa.y );
|
||||
}
|
||||
else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
|
||||
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
|
||||
@ -123,6 +145,13 @@ release_secret_cert_parts( PKT_secret_cert *cert )
|
||||
mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
|
||||
mpi_free( cert->d.elg.x ); cert->d.elg.x = NULL;
|
||||
}
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
mpi_free( cert->d.dsa.p ); cert->d.dsa.p = NULL;
|
||||
mpi_free( cert->d.dsa.q ); cert->d.dsa.q = NULL;
|
||||
mpi_free( cert->d.dsa.g ); cert->d.dsa.g = NULL;
|
||||
mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL;
|
||||
mpi_free( cert->d.dsa.x ); cert->d.dsa.x = NULL;
|
||||
}
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL;
|
||||
mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL;
|
||||
@ -152,6 +181,13 @@ copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s )
|
||||
d->d.elg.y = mpi_copy( s->d.elg.y );
|
||||
d->d.elg.x = mpi_copy( s->d.elg.x );
|
||||
}
|
||||
else if( s->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
d->d.dsa.p = mpi_copy( s->d.dsa.p );
|
||||
d->d.dsa.q = mpi_copy( s->d.dsa.q );
|
||||
d->d.dsa.g = mpi_copy( s->d.dsa.g );
|
||||
d->d.dsa.y = mpi_copy( s->d.dsa.y );
|
||||
d->d.dsa.x = mpi_copy( s->d.dsa.x );
|
||||
}
|
||||
else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
|
||||
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
|
||||
@ -290,6 +326,16 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b )
|
||||
if( mpi_cmp( a->d.elg.y , b->d.elg.y ) )
|
||||
return -1;
|
||||
}
|
||||
else if( a->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
if( mpi_cmp( a->d.dsa.p , b->d.dsa.p ) )
|
||||
return -1;
|
||||
if( mpi_cmp( a->d.dsa.q , b->d.dsa.q ) )
|
||||
return -1;
|
||||
if( mpi_cmp( a->d.dsa.g , b->d.dsa.g ) )
|
||||
return -1;
|
||||
if( mpi_cmp( a->d.dsa.y , b->d.dsa.y ) )
|
||||
return -1;
|
||||
}
|
||||
else if( a->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
if( mpi_cmp( a->d.rsa.rsa_n , b->d.rsa.rsa_n ) )
|
||||
return -1;
|
||||
@ -321,6 +367,16 @@ cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
|
||||
if( mpi_cmp( pkc->d.elg.y , skc->d.elg.y ) )
|
||||
return -1;
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
if( mpi_cmp( pkc->d.dsa.p , skc->d.dsa.p ) )
|
||||
return -1;
|
||||
if( mpi_cmp( pkc->d.dsa.q , skc->d.dsa.q ) )
|
||||
return -1;
|
||||
if( mpi_cmp( pkc->d.dsa.g , skc->d.dsa.g ) )
|
||||
return -1;
|
||||
if( mpi_cmp( pkc->d.dsa.y , skc->d.dsa.y ) )
|
||||
return -1;
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
if( mpi_cmp( pkc->d.rsa.rsa_n , skc->d.rsa.rsa_n ) )
|
||||
return -1;
|
||||
|
157
g10/g10.c
157
g10/g10.c
@ -63,9 +63,13 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ 'c', "symmetric", 0, N_("encryption only with symmetric cipher")},
|
||||
{ 507, "store", 0, N_("store only")},
|
||||
{ 'd', "decrypt", 0, N_("decrypt data (default)")},
|
||||
{ 'k', "list-keys", 0, N_("list keys")},
|
||||
{ 508, "check-keys",0, N_("check signatures on a key in the keyring")},
|
||||
{ 515, "fingerprint", 0, N_("show the fingerprints")},
|
||||
{ 550, "verify" , 0, N_("verify a signature")},
|
||||
#endif
|
||||
{ 551, "list-keys", 0, N_("list keys")},
|
||||
{ 552, "list-sigs", 0, N_("list keys and signatures")},
|
||||
{ 508, "check-sigs",0, N_("check key signatures")},
|
||||
{ 515, "fingerprint", 0, N_("list keys and fingerprints")},
|
||||
#ifdef IS_G10
|
||||
{ 503, "gen-key", 0, N_("generate a new key pair")},
|
||||
{ 506, "sign-key" ,0, N_("make a signature on a key in the keyring")},
|
||||
{ 505, "delete-key",0, N_("remove key from the public keyring")},
|
||||
@ -82,7 +86,6 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ 516, "print-mds" , 0, N_("print all message digests")},
|
||||
{ 513, "gen-prime" , 0, "\r" },
|
||||
{ 548, "gen-random" , 0, "\r" },
|
||||
{ 549, "ext-list-keys", 0, "Print a parsable list of keys" },
|
||||
#endif
|
||||
|
||||
{ 301, NULL, 0, N_("\v\nOptions:\n ") },
|
||||
@ -132,6 +135,7 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ 533, "list-trust-path",0, "\r"},
|
||||
#endif
|
||||
#ifdef IS_G10
|
||||
{ 'k', NULL, 0, "\r"},
|
||||
{ 504, "delete-secret-key",0, "\r" },
|
||||
{ 524, "edit-sig" ,0, "\r"}, /* alias for edit-key */
|
||||
{ 523, "passphrase-fd",1, "\r" },
|
||||
@ -147,6 +151,10 @@ static ARGPARSE_OPTS opts[] = {
|
||||
{ 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */
|
||||
{ 544, "homedir", 2, "\r" }, /* defaults to "~/.gnupg" */
|
||||
{ 545, "no-batch", 0, "\r" },
|
||||
{ 549, "with-colons", 0, "\r"},
|
||||
{ 551, "list-key", 0, "\r" }, /* alias */
|
||||
{ 552, "list-sig", 0, "\r" }, /* alias */
|
||||
{ 508, "check-sig",0, "\r" }, /* alias */
|
||||
|
||||
|
||||
{0} };
|
||||
@ -157,8 +165,9 @@ static ARGPARSE_OPTS opts[] = {
|
||||
enum cmd_values { aNull = 0,
|
||||
aSym, aStore, aEncr, aKeygen, aSign, aSignEncr,
|
||||
aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey,
|
||||
aKMode, aKModeC, aChangePass, aImport,
|
||||
aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs, aExtKeyList,
|
||||
aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys,
|
||||
aListSigs,
|
||||
aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs,
|
||||
aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest,
|
||||
aNOP };
|
||||
|
||||
@ -358,7 +367,7 @@ main( int argc, char **argv )
|
||||
int rc=0;
|
||||
int orig_argc;
|
||||
char **orig_argv;
|
||||
const char *fname, *fname_print;
|
||||
const char *fname;
|
||||
STRLIST sl, remusr= NULL, locusr=NULL;
|
||||
int nrings=0, sec_nrings=0;
|
||||
armor_filter_context_t afx;
|
||||
@ -458,11 +467,10 @@ main( int argc, char **argv )
|
||||
|
||||
#ifdef IS_G10
|
||||
case 'a': opt.armor = 1; opt.no_armor=0; break;
|
||||
case 'b': detached_sig = 1; /* fall trough */
|
||||
case 'c': set_cmd( &cmd , aSym); break;
|
||||
case 'd': break; /* it is default */
|
||||
case 'b': detached_sig = 1; set_cmd( &cmd, aSign ); break;
|
||||
case 'c': set_cmd( &cmd, aSym); break;
|
||||
case 'd': set_cmd( &cmd, aDecrypt); break;
|
||||
case 'e': set_cmd( &cmd, aEncr); break;
|
||||
case 'k': set_cmd( &cmd, aKMode ); break;
|
||||
case 'r': /* store the remote users */
|
||||
sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
|
||||
strcpy(sl->d, pargs.r.ret_str);
|
||||
@ -483,9 +491,6 @@ main( int argc, char **argv )
|
||||
case 505: set_cmd( &cmd, aDeleteKey); break;
|
||||
case 506: set_cmd( &cmd, aSignKey); break;
|
||||
case 507: set_cmd( &cmd, aStore); break;
|
||||
case 508: set_cmd( &cmd, aCheckKeys);
|
||||
opt.check_sigs = 1; opt.list_sigs = 1; break;
|
||||
case 515: opt.fingerprint = 1; break;
|
||||
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
|
||||
case 524: set_cmd( &cmd, aEditSig); break;
|
||||
case 525: set_cmd( &cmd, aChangePass); break;
|
||||
@ -501,6 +506,7 @@ main( int argc, char **argv )
|
||||
case 539: set_cmd( &cmd, aClearsign); break;
|
||||
case 540: secmem_set_flags( secmem_get_flags() | 1 ); break;
|
||||
case 542: set_cmd( &cmd, aGenRevoke); break;
|
||||
case 550: set_cmd( &cmd, aVerify); break;
|
||||
#endif /* IS_G10 */
|
||||
|
||||
#ifdef IS_G10MAINT
|
||||
@ -513,19 +519,21 @@ main( int argc, char **argv )
|
||||
case 546: set_cmd( &cmd, aDeArmor); break;
|
||||
case 547: set_cmd( &cmd, aEnArmor); break;
|
||||
case 548: set_cmd( &cmd, aGenRandom); break;
|
||||
case 549: set_cmd( &cmd, aExtKeyList); break;
|
||||
#endif /* IS_G10MAINT */
|
||||
|
||||
case 'o': opt.outfile = pargs.r.ret_str; break;
|
||||
case 'v': opt.verbose++; opt.list_sigs=1; break;
|
||||
case 'k': set_cmd( &cmd, aKMode ); break;
|
||||
|
||||
case 500: opt.batch = 1; greeting = 0; break;
|
||||
case 501: opt.answer_yes = 1; break;
|
||||
case 502: opt.answer_no = 1; break;
|
||||
case 508: set_cmd( &cmd, aCheckKeys); break;
|
||||
case 509: add_keyring(pargs.r.ret_str); nrings++; break;
|
||||
case 510: opt.debug |= pargs.r.ret_ulong; break;
|
||||
case 511: opt.debug = ~0; break;
|
||||
case 512: set_status_fd( pargs.r.ret_int ); break;
|
||||
case 515: opt.fingerprint = 1; break;
|
||||
case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break;
|
||||
case 518:
|
||||
/* config files may not be nested (silently ignore them) */
|
||||
@ -551,6 +559,9 @@ main( int argc, char **argv )
|
||||
case 543: break; /* no-options */
|
||||
case 544: opt.homedir = pargs.r.ret_str; break;
|
||||
case 545: opt.batch = 0; break;
|
||||
case 549: opt.with_colons=':'; break;
|
||||
case 551: set_cmd( &cmd, aListKeys); break;
|
||||
case 552: set_cmd( &cmd, aListSigs); break;
|
||||
default : errors++; pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
@ -576,9 +587,12 @@ main( int argc, char **argv )
|
||||
/* Okay, we are now working under our real uid */
|
||||
#endif
|
||||
|
||||
write_status( STATUS_ENTER );
|
||||
/*write_status( STATUS_ENTER );*/
|
||||
|
||||
set_debug();
|
||||
if( !cmd && opt.fingerprint )
|
||||
set_cmd( &cmd, aListKeys);
|
||||
|
||||
if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
|
||||
if( cmd == aKModeC ) {
|
||||
opt.fingerprint = 1;
|
||||
@ -593,6 +607,7 @@ main( int argc, char **argv )
|
||||
opt.verbose = opt.verbose > 1;
|
||||
}
|
||||
|
||||
|
||||
/* kludge to let -sat generate a clear text signature */
|
||||
if( opt.textmode && !detached_sig && opt.armor && cmd == aSign )
|
||||
cmd = aClearsign;
|
||||
@ -600,23 +615,24 @@ main( int argc, char **argv )
|
||||
if( opt.verbose > 1 )
|
||||
set_packet_list_mode(1);
|
||||
|
||||
if( cmd != aDeArmor && cmd != aEnArmor ) {
|
||||
/* add the keyrings, but not for some special commands and
|
||||
* not in case of "-kvv userid keyring" */
|
||||
if( cmd != aDeArmor && cmd != aEnArmor
|
||||
&& !(cmd == aKMode && argc == 2 ) ) {
|
||||
if( !sec_nrings || default_keyring ) /* add default secret rings */
|
||||
add_secret_keyring("secring.gpg");
|
||||
if( !nrings || default_keyring ) /* add default ring */
|
||||
add_keyring("pubring.gpg");
|
||||
}
|
||||
|
||||
if( argc ) {
|
||||
fname_print = fname = *argv;
|
||||
}
|
||||
if( argc )
|
||||
fname = *argv;
|
||||
else {
|
||||
fname_print = "[stdin]";
|
||||
fname = NULL;
|
||||
if( get_passphrase_fd() == 0 ) {
|
||||
/* reading data and passphrase form stdin:
|
||||
* we assume the first line is the passphrase, so
|
||||
* we read it now
|
||||
* we better should read it now.
|
||||
*/
|
||||
/* FIXME: doit */
|
||||
}
|
||||
@ -629,6 +645,10 @@ main( int argc, char **argv )
|
||||
case aDeArmor:
|
||||
case aEnArmor:
|
||||
break;
|
||||
case aKMode:
|
||||
case aListKeys:
|
||||
case aCheckKeys:
|
||||
break;
|
||||
case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
|
||||
default: rc = init_trustdb(1, trustdb_name ); break;
|
||||
}
|
||||
@ -642,21 +662,22 @@ main( int argc, char **argv )
|
||||
wrong_args(_("--store [filename]"));
|
||||
if( (rc = encode_store(fname)) )
|
||||
log_error("%s: store failed: %s\n",
|
||||
fname_print, g10_errstr(rc) );
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
#ifdef IS_G10
|
||||
case aSym: /* encrypt the given file only with the symmetric cipher */
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--symmetric [filename]"));
|
||||
if( (rc = encode_symmetric(fname)) )
|
||||
log_error("%s: symmetric encryption failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: symmetric encryption failed: %s\n",
|
||||
print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aEncr: /* encrypt the given file */
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--encrypt [filename]"));
|
||||
if( (rc = encode_crypt(fname,remusr)) )
|
||||
log_error("%s: encryption failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aSign: /* sign the given file */
|
||||
@ -688,7 +709,7 @@ main( int argc, char **argv )
|
||||
else
|
||||
sl = NULL;
|
||||
if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
|
||||
log_error("%s: sign+encrypt failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
|
||||
@ -696,7 +717,19 @@ main( int argc, char **argv )
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--clearsign [filename]"));
|
||||
if( (rc = clearsign_file(fname, locusr, NULL)) )
|
||||
log_error("%s: clearsign failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aVerify:
|
||||
if( (rc = verify_signatures( argc, argv ) ))
|
||||
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aDecrypt:
|
||||
if( argc > 1 )
|
||||
wrong_args(_("--decrypt [filename]"));
|
||||
if( (rc = decrypt_message( fname ) ))
|
||||
log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
|
||||
@ -705,7 +738,7 @@ main( int argc, char **argv )
|
||||
wrong_args(_("--sign-key username"));
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = sign_key(fname, locusr)) )
|
||||
log_error("%s: sign key failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: sign key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aEditSig: /* Edit a key signature */
|
||||
@ -713,7 +746,7 @@ main( int argc, char **argv )
|
||||
wrong_args(_("--edit-sig username"));
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = edit_keysigs(fname)) )
|
||||
log_error("%s: edit signature failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: edit signature failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aDeleteSecretKey:
|
||||
@ -724,7 +757,7 @@ main( int argc, char **argv )
|
||||
wrong_args(_("--delete-key username"));
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
|
||||
log_error("%s: delete key failed: %s\n", fname_print, g10_errstr(rc) );
|
||||
log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
case aChangePass: /* Change the passphrase */
|
||||
@ -732,51 +765,36 @@ main( int argc, char **argv )
|
||||
wrong_args(_("--change-passphrase [username]"));
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = change_passphrase(fname)) )
|
||||
log_error("%s: change passphrase failed: %s\n", fname_print,
|
||||
log_error("%s: change passphrase failed: %s\n", print_fname_stdin(fname),
|
||||
g10_errstr(rc) );
|
||||
break;
|
||||
#endif /* IS_G10 */
|
||||
|
||||
case aCheckKeys:
|
||||
opt.check_sigs = 1;
|
||||
case aListSigs:
|
||||
opt.list_sigs = 1;
|
||||
case aListKeys:
|
||||
std_key_list( argc, argv );
|
||||
break;
|
||||
|
||||
case aKMode: /* list keyring */
|
||||
if( !argc ) { /* list the default public keyrings */
|
||||
int i, seq=0;
|
||||
const char *s;
|
||||
|
||||
while( (s=get_keyring(seq++)) ) {
|
||||
if( !(a = iobuf_open(s)) ) {
|
||||
log_error(_("can't open '%s'\n"), s);
|
||||
continue;
|
||||
}
|
||||
if( seq > 1 )
|
||||
putchar('\n');
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
if( argc < 2 ) /* -kv [userid] */
|
||||
std_key_list( (argc && **argv)? 1:0, argv );
|
||||
else if( argc == 2 ) { /* -kv userid keyring */
|
||||
if( access( argv[1], R_OK ) ) {
|
||||
log_error(_("can't open %s: %s\n"),
|
||||
print_fname_stdin(argv[1]), strerror(errno));
|
||||
}
|
||||
|
||||
}
|
||||
else if( cmd == aCheckKeys ) {
|
||||
log_error("will be soon: --check-keys user-ids\n");
|
||||
}
|
||||
else if( argc == 1) { /* list the given keyring */
|
||||
if( !(a = iobuf_open(fname)) )
|
||||
log_error(_("can't open '%s'\n"), fname_print);
|
||||
else {
|
||||
if( !opt.no_armor ) {
|
||||
memset( &afx, 0, sizeof afx);
|
||||
iobuf_push_filter( a, armor_filter, &afx );
|
||||
}
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
/* add keyring (default keyrings are not registered in this
|
||||
* special case */
|
||||
add_keyring( argv[1] );
|
||||
std_key_list( **argv?1:0, argv );
|
||||
}
|
||||
}
|
||||
else
|
||||
wrong_args(_("-k[v][v][v][c] [keyring]") );
|
||||
wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
|
||||
break;
|
||||
|
||||
#ifdef IS_G10
|
||||
@ -901,13 +919,6 @@ main( int argc, char **argv )
|
||||
list_trust_path( atoi(*argv), argv[1] );
|
||||
break;
|
||||
|
||||
case aExtKeyList:
|
||||
sl = NULL;
|
||||
for( ; argc; argc--, argv++ )
|
||||
add_to_strlist( &sl, *argv );
|
||||
ext_key_list( sl );
|
||||
free_strlist(sl);
|
||||
break;
|
||||
#endif /* IS_G10MAINT */
|
||||
|
||||
|
||||
@ -921,7 +932,7 @@ main( int argc, char **argv )
|
||||
if( argc > 1 )
|
||||
wrong_args(_("[filename]"));
|
||||
if( !(a = iobuf_open(fname)) )
|
||||
log_error(_("can't open '%s'\n"), fname_print);
|
||||
log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
|
||||
else {
|
||||
if( !opt.no_armor ) {
|
||||
if( use_armor_filter( a ) ) {
|
||||
@ -953,7 +964,7 @@ g10_exit( int rc )
|
||||
secmem_dump_stats();
|
||||
secmem_term();
|
||||
rc = rc? rc : log_get_errorcount(0)? 2:0;
|
||||
write_status( STATUS_LEAVE );
|
||||
/*write_status( STATUS_LEAVE );*/
|
||||
exit(rc );
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,7 @@ cache_public_cert( PKT_public_cert *pkc )
|
||||
u32 keyid[2];
|
||||
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|
||||
|| pkc->pubkey_algo == PUBKEY_ALGO_DSA
|
||||
|| pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
keyid_from_pkc( pkc, keyid );
|
||||
}
|
||||
@ -545,6 +546,7 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid,
|
||||
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])
|
||||
@ -596,6 +598,7 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid,
|
||||
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 );
|
||||
@ -657,6 +660,7 @@ scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
|
||||
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 );
|
||||
@ -712,6 +716,7 @@ scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
|
||||
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 );
|
||||
|
@ -259,7 +259,7 @@ import_one( const char *fname, KBNODE keyblock )
|
||||
(ulong)keyid[1], datestr_from_pkc(pkc) );
|
||||
if( uidnode )
|
||||
print_string( stderr, uidnode->pkt->pkt.user_id->name,
|
||||
uidnode->pkt->pkt.user_id->len );
|
||||
uidnode->pkt->pkt.user_id->len, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
if( !uidnode ) {
|
||||
@ -532,7 +532,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
|
||||
log_info("%s: key %08lX, removed userid '",
|
||||
fname, (ulong)keyid[1]);
|
||||
print_string( stderr, node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
node->pkt->pkt.user_id->len, 0 );
|
||||
fputs("'\n", stderr );
|
||||
}
|
||||
delete_kbnode( node ); /* the user-id */
|
||||
|
@ -48,8 +48,8 @@ clone_kbnode( KBNODE node )
|
||||
KBNODE n = m_alloc( sizeof *n );
|
||||
n->next = NULL;
|
||||
n->pkt = node->pkt;
|
||||
n->private_flag |= 2; /* mark cloned */
|
||||
n->flag = 0;
|
||||
n->private_flag = node->private_flag | 2; /* mark cloned */
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ dump_kbnode( KBNODE node )
|
||||
if( node->pkt->pkttype == PKT_USER_ID ) {
|
||||
fputs(" \"", stderr);
|
||||
print_string( stderr, node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len );
|
||||
node->pkt->pkt.user_id->len, 0 );
|
||||
fputs("\"\n", stderr);
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
|
113
g10/keyid.c
113
g10/keyid.c
@ -105,6 +105,60 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
|
||||
return md;
|
||||
}
|
||||
|
||||
static MD_HANDLE
|
||||
dsa_fingerprint_md( PKT_public_cert *pkc )
|
||||
{
|
||||
MD_HANDLE md;
|
||||
byte *buf1, *buf2, *buf3, *buf4 ;
|
||||
byte *p1, *p2, *p3, *p4;
|
||||
unsigned n1, n2, n3, n4;
|
||||
unsigned nb1, nb2, 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 */
|
||||
;
|
||||
nb2 = mpi_get_nbits(pkc->d.dsa.q);
|
||||
p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL );
|
||||
for( ; !*p2 && n2; p2++, n2-- )
|
||||
;
|
||||
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 = 14 + n1 + n2 + 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, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
|
||||
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(buf2);
|
||||
m_free(buf3);
|
||||
m_free(buf4);
|
||||
md_final( md );
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
static MD_HANDLE
|
||||
v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
|
||||
@ -121,6 +175,21 @@ v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
|
||||
return v3_elg_fingerprint_md( &pkc );
|
||||
}
|
||||
|
||||
static MD_HANDLE
|
||||
dsa_fingerprint_md_skc( PKT_secret_cert *skc )
|
||||
{
|
||||
PKT_public_cert pkc;
|
||||
|
||||
pkc.pubkey_algo = skc->pubkey_algo;
|
||||
pkc.timestamp = skc->timestamp;
|
||||
pkc.pubkey_algo = skc->pubkey_algo;
|
||||
pkc.d.dsa.p = skc->d.dsa.p;
|
||||
pkc.d.dsa.q = skc->d.dsa.q;
|
||||
pkc.d.dsa.g = skc->d.dsa.g;
|
||||
pkc.d.dsa.y = skc->d.dsa.y;
|
||||
return dsa_fingerprint_md( &pkc );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Get the keyid from the secret key certificate and put it into keyid
|
||||
@ -145,6 +214,16 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
|
||||
lowbits = keyid[1];
|
||||
md_close(md);
|
||||
}
|
||||
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
const byte *dp;
|
||||
MD_HANDLE md;
|
||||
md = dsa_fingerprint_md_skc(skc);
|
||||
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( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
|
||||
}
|
||||
@ -178,6 +257,16 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
|
||||
lowbits = keyid[1];
|
||||
md_close(md);
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
const byte *dp;
|
||||
MD_HANDLE md;
|
||||
md = dsa_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_RSA ) {
|
||||
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
|
||||
}
|
||||
@ -208,6 +297,9 @@ nbits_from_pkc( PKT_public_cert *pkc )
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
return mpi_get_nbits( pkc->d.elg.p );
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
return mpi_get_nbits( pkc->d.dsa.p );
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
return mpi_get_nbits( pkc->d.rsa.rsa_n );
|
||||
}
|
||||
@ -224,6 +316,9 @@ nbits_from_skc( PKT_secret_cert *skc )
|
||||
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
return mpi_get_nbits( skc->d.elg.p );
|
||||
}
|
||||
else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
return mpi_get_nbits( skc->d.dsa.p );
|
||||
}
|
||||
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
return mpi_get_nbits( skc->d.rsa.rsa_n );
|
||||
}
|
||||
@ -293,6 +388,15 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
|
||||
pkc.d.elg.g = skc->d.elg.g;
|
||||
pkc.d.elg.y = skc->d.elg.y;
|
||||
}
|
||||
else if( pkc.pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
pkc.timestamp = skc->timestamp;
|
||||
pkc.valid_days = skc->valid_days;
|
||||
pkc.pubkey_algo = skc->pubkey_algo;
|
||||
pkc.d.dsa.p = skc->d.dsa.p;
|
||||
pkc.d.dsa.q = skc->d.dsa.q;
|
||||
pkc.d.dsa.g = skc->d.dsa.g;
|
||||
pkc.d.dsa.y = skc->d.dsa.y;
|
||||
}
|
||||
else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n;
|
||||
pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e;
|
||||
@ -322,6 +426,15 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
|
||||
memcpy(array, dp, 20 );
|
||||
md_close(md);
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
MD_HANDLE md;
|
||||
md = dsa_fingerprint_md(pkc);
|
||||
dp = md_read( md, DIGEST_ALGO_SHA1 );
|
||||
array = m_alloc( 20 );
|
||||
len = 20;
|
||||
memcpy(array, dp, 20 );
|
||||
md_close(md);
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
MD_HANDLE md;
|
||||
|
||||
|
224
g10/keylist.c
224
g10/keylist.c
@ -32,17 +32,231 @@
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "trustdb.h"
|
||||
#include "ttyio.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
|
||||
static void list_all(void);
|
||||
static void list_one(const char *name);
|
||||
static void fingerprint( PKT_public_cert *pkc );
|
||||
|
||||
|
||||
/****************
|
||||
* List the keys in a special forma which is extensible and easy to parse
|
||||
* If NAMES is NULL; the complte keyring is listed
|
||||
*
|
||||
* List the keys
|
||||
* If NNAMES is 0; all available keys are listed
|
||||
*/
|
||||
void
|
||||
ext_key_list( STRLIST names )
|
||||
std_key_list( int nnames, char **names )
|
||||
{
|
||||
if( !nnames )
|
||||
list_all();
|
||||
else { /* List by user id */
|
||||
for( ; nnames ; nnames--, names++ )
|
||||
list_one( *names );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
list_all()
|
||||
{
|
||||
int i, seq=0;
|
||||
const char *s;
|
||||
IOBUF a;
|
||||
|
||||
while( (s=get_keyring(seq++)) ) {
|
||||
if( !(a = iobuf_open(s)) ) {
|
||||
log_error(_("can't open %s: %s\n"), s, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if( seq > 1 )
|
||||
putchar('\n');
|
||||
printf("%s\n", s );
|
||||
for(i=strlen(s); i; i-- )
|
||||
putchar('-');
|
||||
putchar('\n');
|
||||
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
list_one( const char *name )
|
||||
{
|
||||
int rc = 0;
|
||||
KBNODE keyblock = NULL;
|
||||
KBNODE kbctx;
|
||||
KBNODE node;
|
||||
KBPOS kbpos;
|
||||
PKT_public_cert *pkc;
|
||||
u32 keyid[2];
|
||||
int any=0;
|
||||
|
||||
/* search the userid */
|
||||
rc = find_keyblock_byname( &kbpos, name );
|
||||
if( rc ) {
|
||||
log_error("%s: user not found\n", name );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* read the keyblock */
|
||||
rc = read_keyblock( &kbpos, &keyblock );
|
||||
if( rc ) {
|
||||
log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* get the keyid from the keyblock */
|
||||
node = find_kbnode( keyblock, PKT_PUBLIC_CERT );
|
||||
if( !node ) {
|
||||
log_error("Oops; public key not found anymore!\n");
|
||||
goto leave;
|
||||
}
|
||||
|
||||
pkc = node->pkt->pkt.public_cert;
|
||||
keyid_from_pkc( pkc, keyid );
|
||||
if( opt.with_colons )
|
||||
printf("pub::%u:%d:%08lX%08lX:%s:::",
|
||||
/* fixme: add trust value here */
|
||||
nbits_from_pkc( pkc ),
|
||||
pkc->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_pkc( pkc )
|
||||
/* fixme: add LID and ownertrust here */
|
||||
);
|
||||
else
|
||||
printf("pub %4u%c/%08lX %s ", nbits_from_pkc( pkc ),
|
||||
pubkey_letter( pkc->pubkey_algo ),
|
||||
(ulong)keyid[1],
|
||||
datestr_from_pkc( pkc ) );
|
||||
|
||||
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID ) {
|
||||
if( any ) {
|
||||
if( opt.with_colons )
|
||||
printf("uid::::::::");
|
||||
else
|
||||
printf("uid%*s", 28, "");
|
||||
}
|
||||
print_string( stdout, node->pkt->pkt.user_id->name,
|
||||
node->pkt->pkt.user_id->len, opt.with_colons );
|
||||
if( opt.with_colons )
|
||||
putchar(':');
|
||||
putchar('\n');
|
||||
if( !any ) {
|
||||
if( opt.fingerprint )
|
||||
fingerprint( pkc );
|
||||
any = 1;
|
||||
}
|
||||
}
|
||||
else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
PKT_signature *sig = node->pkt->pkt.signature;
|
||||
int sigrc;
|
||||
|
||||
if( !any ) { /* no user id, (maybe a revocation follows)*/
|
||||
if( sig->sig_class == 0x20 )
|
||||
puts("[revoked]");
|
||||
else
|
||||
putchar('\n');
|
||||
if( opt.fingerprint )
|
||||
fingerprint( pkc );
|
||||
any=1;
|
||||
}
|
||||
|
||||
if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
|
||||
fputs("rev", stdout);
|
||||
else if( (sig->sig_class&~3) == 0x10 )
|
||||
fputs("sig", stdout);
|
||||
else {
|
||||
if( opt.with_colons )
|
||||
printf("sig:::::::::%02x:\n",sig->sig_class );
|
||||
else
|
||||
printf("sig "
|
||||
"[unexpected signature class 0x%02x]\n",sig->sig_class );
|
||||
continue;
|
||||
}
|
||||
if( opt.check_sigs ) {
|
||||
fflush(stdout);
|
||||
rc = check_key_signature( keyblock, node, NULL );
|
||||
switch( rc ) {
|
||||
case 0: sigrc = '!'; break;
|
||||
case G10ERR_BAD_SIGN: sigrc = '-'; break;
|
||||
case G10ERR_NO_PUBKEY: sigrc = '?'; break;
|
||||
default: sigrc = '%'; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rc = 0;
|
||||
sigrc = ' ';
|
||||
}
|
||||
if( opt.with_colons ) {
|
||||
putchar(':');
|
||||
if( sigrc != ' ' )
|
||||
putchar(sigrc);
|
||||
printf(":::%08lX%08lX:%s:::", (ulong)sig->keyid[0],
|
||||
(ulong)sig->keyid[1], datestr_from_sig(sig));
|
||||
}
|
||||
else
|
||||
printf("%c %08lX %s ",
|
||||
sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
|
||||
if( sigrc == '%' )
|
||||
printf("[%s] ", g10_errstr(rc) );
|
||||
else if( sigrc == '?' )
|
||||
;
|
||||
else {
|
||||
size_t n;
|
||||
char *p = get_user_id( sig->keyid, &n );
|
||||
print_string( stdout, p, n, opt.with_colons );
|
||||
m_free(p);
|
||||
}
|
||||
if( opt.with_colons )
|
||||
printf(":%02x:", sig->sig_class );
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
if( !any ) {/* oops, no user id */
|
||||
if( opt.with_colons )
|
||||
putchar(':');
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
}
|
||||
|
||||
static void
|
||||
fingerprint( PKT_public_cert *pkc )
|
||||
{
|
||||
byte *array, *p;
|
||||
size_t i, n;
|
||||
|
||||
p = array = fingerprint_from_pkc( pkc, &n );
|
||||
if( opt.with_colons ) {
|
||||
printf("fpr::::::::");
|
||||
for(i=0; i < n ; i++, p++ )
|
||||
printf("%02X", *p );
|
||||
putchar(':');
|
||||
}
|
||||
else {
|
||||
printf(" Key fingerprint =");
|
||||
if( n == 20 ) {
|
||||
for(i=0; i < n ; i++, i++, p += 2 ) {
|
||||
if( i == 10 )
|
||||
putchar(' ');
|
||||
printf(" %02X%02X", *p, p[1] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i=0; i < n ; i++, p++ ) {
|
||||
if( i && !(i%8) )
|
||||
putchar(' ');
|
||||
printf(" %02X", *p );
|
||||
}
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
m_free(array);
|
||||
}
|
||||
|
||||
|
15
g10/main.h
15
g10/main.h
@ -81,6 +81,10 @@ void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
|
||||
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
MD_HANDLE md, int digest_algo );
|
||||
|
||||
/*-- dsa.c --*/
|
||||
void g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
MD_HANDLE md, int digest_algo );
|
||||
|
||||
/*-- rsa.c --*/
|
||||
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
|
||||
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
@ -98,6 +102,15 @@ int enarmor_file( const char *fname );
|
||||
int gen_revoke( const char *uname );
|
||||
|
||||
/*-- keylist.c --*/
|
||||
void ext_key_list( STRLIST names );
|
||||
void std_key_list( int nnames, char **names );
|
||||
|
||||
/*-- verify.c --*/
|
||||
int verify_signatures( int nfiles, char **files );
|
||||
|
||||
/*-- decrypt.c --*/
|
||||
int decrypt_message( const char *filename );
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int hash_datafiles( MD_HANDLE md, STRLIST files, int textmode );
|
||||
|
||||
#endif /*G10_MAIN_H*/
|
||||
|
214
g10/mainproc.c
214
g10/mainproc.c
@ -21,6 +21,7 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "packet.h"
|
||||
@ -45,6 +46,9 @@ typedef struct {
|
||||
PKT_secret_cert *last_seckey;
|
||||
PKT_user_id *last_user_id;
|
||||
md_filter_context_t mfx;
|
||||
int sigs_only; /* process only signatures and reject all other stuff */
|
||||
int encrypt_only; /* process onyl encrytion messages */
|
||||
STRLIST signed_data;
|
||||
DEK *dek;
|
||||
int last_was_pubkey_enc;
|
||||
KBNODE list; /* the current list of packets */
|
||||
@ -53,6 +57,7 @@ typedef struct {
|
||||
} *CTX;
|
||||
|
||||
|
||||
static int do_proc_packets( CTX c, IOBUF a );
|
||||
|
||||
static void list_node( CTX c, KBNODE node );
|
||||
static void proc_tree( CTX c, KBNODE node );
|
||||
@ -155,6 +160,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|
||||
enc = pkt->pkt.pubkey_enc;
|
||||
/*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
|
||||
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
|
||||
|| enc->pubkey_algo == PUBKEY_ALGO_DSA
|
||||
|| enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
m_free(c->dek ); /* paranoid: delete a pending DEK */
|
||||
c->dek = m_alloc_secure( sizeof *c->dek );
|
||||
@ -234,6 +240,18 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
proc_compressed_cb( IOBUF a, void *info )
|
||||
{
|
||||
return proc_signature_packets( a, ((CTX)info)->signed_data );
|
||||
}
|
||||
|
||||
static int
|
||||
proc_encrypt_cb( IOBUF a, void *info )
|
||||
{
|
||||
return proc_encryption_packets( a );
|
||||
}
|
||||
|
||||
static void
|
||||
proc_compressed( CTX c, PACKET *pkt )
|
||||
{
|
||||
@ -241,7 +259,12 @@ proc_compressed( CTX c, PACKET *pkt )
|
||||
int rc;
|
||||
|
||||
/*printf("zip: compressed data packet\n");*/
|
||||
rc = handle_compressed( zd );
|
||||
if( c->sigs_only )
|
||||
rc = handle_compressed( zd, proc_compressed_cb, c );
|
||||
else if( c->encrypt_only )
|
||||
rc = handle_compressed( zd, proc_encrypt_cb, c );
|
||||
else
|
||||
rc = handle_compressed( zd, NULL, NULL );
|
||||
if( rc )
|
||||
log_error("uncompressing failed: %s\n", g10_errstr(rc));
|
||||
free_packet(pkt);
|
||||
@ -337,7 +360,8 @@ print_userid( PACKET *pkt )
|
||||
printf("ERROR: unexpected packet type %d", pkt->pkttype );
|
||||
return;
|
||||
}
|
||||
print_string( stdout, pkt->pkt.user_id->name, pkt->pkt.user_id->len );
|
||||
print_string( stdout, pkt->pkt.user_id->name, pkt->pkt.user_id->len,
|
||||
opt.with_colons );
|
||||
}
|
||||
|
||||
|
||||
@ -349,19 +373,27 @@ print_fingerprint( PKT_public_cert *pkc, PKT_secret_cert *skc )
|
||||
|
||||
p = array = skc? fingerprint_from_skc( skc, &n )
|
||||
: fingerprint_from_pkc( pkc, &n );
|
||||
printf(" Key fingerprint =");
|
||||
if( n == 20 ) {
|
||||
for(i=0; i < n ; i++, i++, p += 2 ) {
|
||||
if( i == 10 )
|
||||
putchar(' ');
|
||||
printf(" %02X%02X", *p, p[1] );
|
||||
}
|
||||
if( opt.with_colons ) {
|
||||
printf("fpr::::::::");
|
||||
for(i=0; i < n ; i++, p++ )
|
||||
printf("%02X", *p );
|
||||
putchar(':');
|
||||
}
|
||||
else {
|
||||
for(i=0; i < n ; i++, p++ ) {
|
||||
if( i && !(i%8) )
|
||||
putchar(' ');
|
||||
printf(" %02X", *p );
|
||||
printf(" Key fingerprint =");
|
||||
if( n == 20 ) {
|
||||
for(i=0; i < n ; i++, i++, p += 2 ) {
|
||||
if( i == 10 )
|
||||
putchar(' ');
|
||||
printf(" %02X%02X", *p, p[1] );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i=0; i < n ; i++, p++ ) {
|
||||
if( i && !(i%8) )
|
||||
putchar(' ');
|
||||
printf(" %02X", *p );
|
||||
}
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
@ -383,24 +415,47 @@ list_node( CTX c, KBNODE node )
|
||||
else if( node->pkt->pkttype == PKT_PUBLIC_CERT ) {
|
||||
PKT_public_cert *pkc = node->pkt->pkt.public_cert;
|
||||
|
||||
printf("pub %4u%c/%08lX %s ", nbits_from_pkc( pkc ),
|
||||
if( opt.with_colons ) {
|
||||
u32 keyid[2];
|
||||
keyid_from_pkc( pkc, keyid );
|
||||
printf("pub::%u:%d:%08lX%08lX:%s:::",
|
||||
/* fixme: add trust value here */
|
||||
nbits_from_pkc( pkc ),
|
||||
pkc->pubkey_algo,
|
||||
(ulong)keyid[0],(ulong)keyid[1],
|
||||
datestr_from_pkc( pkc )
|
||||
/* fixme: add LID and ownertrust here */
|
||||
);
|
||||
}
|
||||
else
|
||||
printf("pub %4u%c/%08lX %s ", nbits_from_pkc( pkc ),
|
||||
pubkey_letter( pkc->pubkey_algo ),
|
||||
(ulong)keyid_from_pkc( pkc, NULL ),
|
||||
datestr_from_pkc( pkc ) );
|
||||
/* and now list all userids with their signatures */
|
||||
for( node = node->next; node; node = node->next ) {
|
||||
if( any != 2 && node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
if( !any )
|
||||
putchar('\n');
|
||||
if( !any ) {
|
||||
if( node->pkt->pkt.signature->sig_class == 0x20 )
|
||||
puts("[revoked]");
|
||||
else
|
||||
putchar('\n');
|
||||
}
|
||||
list_node(c, node );
|
||||
any = 1;
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_USER_ID ) {
|
||||
KBNODE n;
|
||||
|
||||
if( any )
|
||||
printf( "%*s", 31, "" );
|
||||
if( any ) {
|
||||
if( opt.with_colons )
|
||||
printf("uid::::::::");
|
||||
else
|
||||
printf( "uid%*s", 28, "" );
|
||||
}
|
||||
print_userid( node->pkt );
|
||||
if( opt.with_colons )
|
||||
putchar(':');
|
||||
putchar('\n');
|
||||
if( opt.fingerprint && !any )
|
||||
print_fingerprint( pkc, NULL );
|
||||
@ -457,17 +512,27 @@ list_node( CTX c, KBNODE node )
|
||||
default: sigrc = '%'; break;
|
||||
}
|
||||
}
|
||||
printf("%c %08lX %s ",
|
||||
sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
|
||||
if( opt.with_colons ) {
|
||||
putchar(':');
|
||||
if( sigrc != ' ' )
|
||||
putchar(sigrc);
|
||||
printf(":::%08lX%08lX:%s:::", (ulong)sig->keyid[0],
|
||||
(ulong)sig->keyid[1], datestr_from_sig(sig));
|
||||
}
|
||||
else
|
||||
printf("%c %08lX %s ",
|
||||
sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
|
||||
if( sigrc == '%' )
|
||||
printf("[%s] ", g10_errstr(rc2) );
|
||||
else if( sigrc == '?' )
|
||||
;
|
||||
else {
|
||||
p = get_user_id( sig->keyid, &n );
|
||||
print_string( stdout, p, n );
|
||||
print_string( stdout, p, n, opt.with_colons );
|
||||
m_free(p);
|
||||
}
|
||||
if( opt.with_colons )
|
||||
printf(":%02x:", sig->sig_class );
|
||||
putchar('\n');
|
||||
}
|
||||
else
|
||||
@ -479,8 +544,40 @@ int
|
||||
proc_packets( IOBUF a )
|
||||
{
|
||||
CTX c = m_alloc_clear( sizeof *c );
|
||||
PACKET *pkt = m_alloc( sizeof *pkt );
|
||||
int rc = do_proc_packets( c, a );
|
||||
m_free( c );
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
proc_signature_packets( IOBUF a, STRLIST signedfiles )
|
||||
{
|
||||
CTX c = m_alloc_clear( sizeof *c );
|
||||
int rc;
|
||||
c->sigs_only = 1;
|
||||
c->signed_data = signedfiles;
|
||||
rc = do_proc_packets( c, a );
|
||||
m_free( c );
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
proc_encryption_packets( IOBUF a )
|
||||
{
|
||||
CTX c = m_alloc_clear( sizeof *c );
|
||||
int rc;
|
||||
c->encrypt_only = 1;
|
||||
rc = do_proc_packets( c, a );
|
||||
m_free( c );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
do_proc_packets( CTX c, IOBUF a )
|
||||
{
|
||||
PACKET *pkt = m_alloc( sizeof *pkt );
|
||||
int rc=0;
|
||||
int newpkt;
|
||||
|
||||
c->iobuf = a;
|
||||
@ -507,6 +604,38 @@ proc_packets( IOBUF a )
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
}
|
||||
else if( c->sigs_only ) {
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_CERT:
|
||||
case PKT_SECRET_CERT:
|
||||
case PKT_USER_ID:
|
||||
case PKT_PUBKEY_ENC:
|
||||
case PKT_ENCRYPTED:
|
||||
rc = G10ERR_UNEXPECTED;
|
||||
goto leave;
|
||||
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
|
||||
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
}
|
||||
else if( c->encrypt_only ) {
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_CERT:
|
||||
case PKT_SECRET_CERT:
|
||||
case PKT_USER_ID:
|
||||
rc = G10ERR_UNEXPECTED;
|
||||
goto leave;
|
||||
case PKT_SIGNATURE: newpkt = add_signature( c, pkt ); break;
|
||||
case PKT_PUBKEY_ENC: proc_pubkey_enc( c, pkt ); break;
|
||||
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
|
||||
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch( pkt->pkttype ) {
|
||||
case PKT_PUBLIC_CERT: newpkt = add_public_cert( c, pkt ); break;
|
||||
@ -533,14 +662,15 @@ proc_packets( IOBUF a )
|
||||
else
|
||||
free_packet(pkt);
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
leave:
|
||||
release_list( c );
|
||||
m_free(c->dek);
|
||||
free_packet( pkt );
|
||||
m_free( pkt );
|
||||
free_md_filter_context( &c->mfx );
|
||||
m_free( c );
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -549,7 +679,7 @@ print_keyid( FILE *fp, u32 *keyid )
|
||||
{
|
||||
size_t n;
|
||||
char *p = get_user_id( keyid, &n );
|
||||
print_string( fp, p, n );
|
||||
print_string( fp, p, n, opt.with_colons );
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
@ -562,15 +692,18 @@ check_sig_and_print( CTX c, KBNODE node )
|
||||
int rc;
|
||||
|
||||
rc = do_check_sig(c, node );
|
||||
if( !rc ) {
|
||||
write_status( STATUS_GOODSIG );
|
||||
log_info("Good signature from ");
|
||||
print_keyid( stderr, sig->keyid );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
else if( rc == G10ERR_BAD_SIGN ) {
|
||||
write_status( STATUS_BADSIG );
|
||||
log_error("BAD signature from ");
|
||||
if( !rc || rc == G10ERR_BAD_SIGN ) {
|
||||
char *p, *buf;
|
||||
|
||||
p = get_user_id_string( sig->keyid );
|
||||
buf = m_alloc( 20 + strlen(p) );
|
||||
sprintf(buf, "%lu %s", (ulong)sig->timestamp, p );
|
||||
m_free(p);
|
||||
if( (p=strchr(buf,'\n')) )
|
||||
*p = 0; /* just in case ... */
|
||||
write_status_text( rc? STATUS_BADSIG : STATUS_GOODSIG, buf );
|
||||
m_free(buf);
|
||||
log_info("%s signature from ", rc? "BAD":"Good");
|
||||
print_keyid( stderr, sig->keyid );
|
||||
putc('\n', stderr);
|
||||
if( opt.batch )
|
||||
@ -607,12 +740,17 @@ proc_tree( CTX c, KBNODE node )
|
||||
free_md_filter_context( &c->mfx );
|
||||
/* prepare to create all requested message digests */
|
||||
c->mfx.md = md_open(0, 0);
|
||||
/* fixme: why looking for the signature packet and not 1passpacket*/
|
||||
for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) {
|
||||
md_enable( c->mfx.md,
|
||||
digest_algo_from_sig(n1->pkt->pkt.signature));
|
||||
}
|
||||
/* ask for file and hash it */
|
||||
rc = ask_for_detached_datafile( &c->mfx,
|
||||
if( c->sigs_only )
|
||||
rc = hash_datafiles( c->mfx.md, c->signed_data,
|
||||
n1->pkt->pkt.onepass_sig->sig_class == 0x01 );
|
||||
else
|
||||
rc = ask_for_detached_datafile( &c->mfx,
|
||||
iobuf_get_fname(c->iobuf));
|
||||
if( rc ) {
|
||||
log_error("can't hash datafile: %s\n", g10_errstr(rc));
|
||||
@ -629,7 +767,11 @@ proc_tree( CTX c, KBNODE node )
|
||||
if( !c->have_data ) {
|
||||
free_md_filter_context( &c->mfx );
|
||||
c->mfx.md = md_open(digest_algo_from_sig(sig), 0);
|
||||
rc = ask_for_detached_datafile( &c->mfx,
|
||||
if( c->sigs_only )
|
||||
rc = hash_datafiles( c->mfx.md, c->signed_data,
|
||||
sig->sig_class == 0x01 );
|
||||
else
|
||||
rc = ask_for_detached_datafile( &c->mfx,
|
||||
iobuf_get_fname(c->iobuf));
|
||||
if( rc ) {
|
||||
log_error("can't hash datafile: %s\n", g10_errstr(rc));
|
||||
|
@ -42,6 +42,8 @@
|
||||
int
|
||||
overwrite_filep( const char *fname )
|
||||
{
|
||||
if( !fname || (*fname == '-' && !fname[1]) )
|
||||
return 0; /* stdout */
|
||||
if( !access( fname, F_OK ) ) {
|
||||
char *p;
|
||||
int okay;
|
||||
@ -55,7 +57,6 @@ overwrite_filep( const char *fname )
|
||||
okay = 0;
|
||||
|
||||
while( !okay ) {
|
||||
if( !okay )
|
||||
if( first ) {
|
||||
tty_printf("File '%s' exists. ", fname);
|
||||
first = 0;
|
||||
@ -91,7 +92,7 @@ open_outfile( const char *iname, int mode )
|
||||
IOBUF a = NULL;
|
||||
int rc;
|
||||
|
||||
if( !iname && !opt.outfile ) {
|
||||
if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) {
|
||||
if( !(a = iobuf_create(NULL)) )
|
||||
log_error("can't open [stdout]: %s\n", strerror(errno) );
|
||||
else if( opt.verbose )
|
||||
@ -133,7 +134,7 @@ open_sigfile( const char *iname )
|
||||
IOBUF a = NULL;
|
||||
size_t len;
|
||||
|
||||
if( iname ) {
|
||||
if( iname && !(*iname == '-' && !iname[1]) ) {
|
||||
len = strlen(iname);
|
||||
if( len > 4 && ( !strcmp(iname + len - 4, ".sig")
|
||||
|| !strcmp(iname + len - 4, ".asc")) ) {
|
||||
|
@ -31,7 +31,7 @@ struct {
|
||||
int answer_yes; /* answer yes on most questions */
|
||||
int answer_no; /* answer no on most questions */
|
||||
int check_sigs; /* check key signatures */
|
||||
int reserved1;
|
||||
int with_colons;
|
||||
int fingerprint; /* list fingerprints */
|
||||
int list_sigs; /* list signatures */
|
||||
int no_armor;
|
||||
|
42
g10/packet.h
42
g10/packet.h
@ -75,18 +75,22 @@ typedef struct {
|
||||
u32 keyid[2]; /* 64 bit keyid */
|
||||
ulong local_id; /* internal use, valid if > 0 */
|
||||
u32 timestamp; /* signature made */
|
||||
byte version;
|
||||
byte sig_class; /* sig classification, append for MD calculation*/
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
/* (PUBKEY_ALGO_xxx) */
|
||||
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
|
||||
byte *hashed_data; /* all subpackets with hashed data (v4 only) */
|
||||
byte *unhashed_data; /* ditto for unhashed data */
|
||||
byte digest_start[2]; /* first 2 bytes of the digest */
|
||||
union {
|
||||
struct {
|
||||
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
|
||||
byte digest_start[2]; /* first 2 byte of the digest */
|
||||
MPI a, b; /* integers with the digest */
|
||||
} elg;
|
||||
struct {
|
||||
byte digest_algo; /* algorithm used for digest (DIGEST_ALGO_xxxx) */
|
||||
byte digest_start[2]; /* first 2 byte of the digest */
|
||||
MPI r, s; /* integers with the digest */
|
||||
} dsa;
|
||||
struct {
|
||||
MPI rsa_integer; /* the encrypted digest */
|
||||
} rsa;
|
||||
} d;
|
||||
@ -106,6 +110,12 @@ typedef struct {
|
||||
MPI g; /* group generator */
|
||||
MPI y; /* g^x mod p */
|
||||
} elg;
|
||||
struct {
|
||||
MPI p; /* prime */
|
||||
MPI q; /* group order */
|
||||
MPI g; /* group generator */
|
||||
MPI y; /* g^x mod p */
|
||||
} dsa;
|
||||
struct {
|
||||
MPI rsa_n; /* public modulus */
|
||||
MPI rsa_e; /* public exponent */
|
||||
@ -138,6 +148,25 @@ typedef struct {
|
||||
} protect; /* when protected, the MPIs above are pointers
|
||||
* to plain storage */
|
||||
} elg;
|
||||
struct {
|
||||
MPI p; /* prime */
|
||||
MPI q; /* group order */
|
||||
MPI g; /* group generator */
|
||||
MPI y; /* g^x mod p */
|
||||
MPI x; /* secret exponent */
|
||||
u16 csum; /* checksum */
|
||||
byte is_protected; /* The above infos are protected and must */
|
||||
/* be decrypteded before use. */
|
||||
struct {
|
||||
byte algo; /* cipher used to protect the secret informations*/
|
||||
byte s2k;
|
||||
byte hash;
|
||||
byte salt[8];
|
||||
byte count;
|
||||
byte iv[8]; /* initialization vector for CFB mode */
|
||||
} protect; /* when protected, the MPIs above are pointers
|
||||
* to plain storage */
|
||||
} dsa;
|
||||
struct {
|
||||
MPI rsa_n; /* public modulus */
|
||||
MPI rsa_e; /* public exponent */
|
||||
@ -215,6 +244,8 @@ struct packet_struct {
|
||||
|
||||
/*-- mainproc.c --*/
|
||||
int proc_packets( IOBUF a );
|
||||
int proc_signature_packets( IOBUF a, STRLIST signedfiles );
|
||||
int proc_encryption_packets( IOBUF a );
|
||||
int list_packets( IOBUF a );
|
||||
|
||||
/*-- parse-packet.c --*/
|
||||
@ -260,7 +291,8 @@ int protect_secret_key( PKT_secret_cert *cert, DEK *dek );
|
||||
int get_session_key( PKT_pubkey_enc *k, DEK *dek );
|
||||
|
||||
/*-- compress.c --*/
|
||||
int handle_compressed( PKT_compressed *zd );
|
||||
int handle_compressed( PKT_compressed *cd,
|
||||
int (*callback)(IOBUF, void *), void *passthru );
|
||||
|
||||
/*-- encr-data.c --*/
|
||||
int decrypt_data( PKT_encrypted *ed, DEK *dek );
|
||||
|
@ -96,6 +96,17 @@ read_32(IOBUF inp)
|
||||
return a;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
buffer_to_u32( const byte *buffer )
|
||||
{
|
||||
unsigned long a;
|
||||
a = *buffer << 24;
|
||||
a |= buffer[1] << 16;
|
||||
a |= buffer[2] << 8;
|
||||
a |= buffer[3];
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
set_packet_list_mode( int mode )
|
||||
{
|
||||
@ -466,49 +477,210 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
||||
}
|
||||
|
||||
|
||||
static const byte *
|
||||
parse_subpkt( const byte *buffer, int reqtype )
|
||||
{
|
||||
int buflen = (*buffer << 8) | buffer[1];
|
||||
int type;
|
||||
int critical;
|
||||
size_t n;
|
||||
|
||||
buffer += 2;
|
||||
for(;;) {
|
||||
if( !buflen )
|
||||
return NULL; /* end of packets; not found */
|
||||
n = *buffer++; buflen--;
|
||||
if( n >= 192 ) {
|
||||
if( buflen < 2 )
|
||||
goto too_short;
|
||||
n = (( n - 192 ) << 8) + *buffer + 192;
|
||||
buflen--;
|
||||
}
|
||||
if( buflen < n )
|
||||
goto too_short;
|
||||
type = *buffer;
|
||||
if( type & 0x80 ) {
|
||||
type &= 0x7f;
|
||||
critical = 1;
|
||||
}
|
||||
else
|
||||
critical = 0;
|
||||
if( reqtype < 0 ) { /* list packets */
|
||||
printf("\t%ssubpacket %d of length %u (%s)\n",
|
||||
reqtype == -1 ? "hashed ":"", type, n,
|
||||
type == 2 ? "signature creation time"
|
||||
: type == 3 ? "signature expiration time"
|
||||
: type == 4 ? "exportable"
|
||||
: type == 5 ? "trust signature"
|
||||
: type == 6 ? "regular expression"
|
||||
: type == 7 ? "revocable"
|
||||
: type == 9 ? "key expiration time"
|
||||
: type ==10 ? "additional recipient request"
|
||||
: type ==11 ? "preferred symmetric algorithms"
|
||||
: type ==12 ? "revocation key"
|
||||
: type ==16 ? "issuer key ID"
|
||||
: type ==20 ? "notation data"
|
||||
: type ==21 ? "preferred hash algorithms"
|
||||
: type ==22 ? "preferred compression algorithms"
|
||||
: type ==23 ? "key server preferences"
|
||||
: type ==24 ? "preferred key server"
|
||||
: "?");
|
||||
}
|
||||
else if( type == reqtype )
|
||||
break; /* found */
|
||||
buffer += n; buflen -=n;
|
||||
}
|
||||
buffer++;
|
||||
n--;
|
||||
if( n > buflen )
|
||||
goto too_short;
|
||||
switch( type ) {
|
||||
case 2: /* signature creation time */
|
||||
if( n < 4 )
|
||||
break;
|
||||
return buffer;
|
||||
case 16:/* issuer key ID */
|
||||
if( n < 8 )
|
||||
break;
|
||||
return buffer;
|
||||
case 3: /* signature expiration time */
|
||||
case 4: /* exportable */
|
||||
case 5: /* trust signature */
|
||||
case 6: /* regular expression */
|
||||
case 7: /* revocable */
|
||||
case 9: /* key expiration time */
|
||||
case 10:/* additional recipient request */
|
||||
case 11:/* preferred symmetric algorithms */
|
||||
case 12:/* revocation key */
|
||||
case 20:/* notation data */
|
||||
case 21:/* preferred hash algorithms */
|
||||
case 22:/* preferred compression algorithms */
|
||||
case 23:/* key server preferences */
|
||||
case 24:/* preferred key server */
|
||||
default: BUG(); /* not yet needed */
|
||||
}
|
||||
log_error("subpacket of type %d too short\n", type);
|
||||
return NULL;
|
||||
|
||||
too_short:
|
||||
log_error("buffer shorter than subpacket\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PKT_signature *sig )
|
||||
{
|
||||
int version, md5_len;
|
||||
int md5_len=0;
|
||||
unsigned n;
|
||||
int is_v4=0;
|
||||
int rc=0;
|
||||
|
||||
if( pktlen < 16 ) {
|
||||
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);
|
||||
sig->version = iobuf_get_noeof(inp); pktlen--;
|
||||
if( sig->version == 4 )
|
||||
is_v4=1;
|
||||
else if( sig->version != 2 && sig->version != 3 ) {
|
||||
log_error("packet(%d) with unknown version %d\n", pkttype, sig->version);
|
||||
goto leave;
|
||||
}
|
||||
md5_len = iobuf_get_noeof(inp); pktlen--;
|
||||
|
||||
if( !is_v4 ) {
|
||||
md5_len = iobuf_get_noeof(inp); pktlen--;
|
||||
}
|
||||
sig->sig_class = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->timestamp = read_32(inp); pktlen -= 4;
|
||||
sig->keyid[0] = read_32(inp); pktlen -= 4;
|
||||
sig->keyid[1] = read_32(inp); pktlen -= 4;
|
||||
if( !is_v4 ) {
|
||||
sig->timestamp = read_32(inp); pktlen -= 4;
|
||||
sig->keyid[0] = read_32(inp); pktlen -= 4;
|
||||
sig->keyid[1] = read_32(inp); pktlen -= 4;
|
||||
}
|
||||
sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
if( list_mode )
|
||||
printf(":signature packet: keyid %08lX%08lX\n"
|
||||
"\tversion %d, created %lu, md5len %d, sigclass %02x\n",
|
||||
(ulong)sig->keyid[0], (ulong)sig->keyid[1],
|
||||
version, (ulong)sig->timestamp, md5_len, sig->sig_class );
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
if( pktlen < 5 ) {
|
||||
log_error("packet(%d) too short\n", pkttype);
|
||||
sig->digest_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
if( is_v4 ) { /* read subpackets */
|
||||
n = read_16(inp); pktlen -= 2; /* length of hashed data */
|
||||
if( n > 10000 ) {
|
||||
log_error("signature packet: hashed data too long\n");
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
sig->d.elg.digest_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->d.elg.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->d.elg.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
|
||||
if( n ) {
|
||||
sig->hashed_data = m_alloc( n + 2 );
|
||||
sig->hashed_data[0] = n << 8;
|
||||
sig->hashed_data[1] = n;
|
||||
if( iobuf_read(inp, sig->hashed_data+2, n ) != n ) {
|
||||
log_error("premature eof while reading hashed signature data\n");
|
||||
rc = -1;
|
||||
goto leave;
|
||||
}
|
||||
pktlen -= n;
|
||||
}
|
||||
n = read_16(inp); pktlen -= 2; /* length of unhashed data */
|
||||
if( n > 10000 ) {
|
||||
log_error("signature packet: unhashed data too long\n");
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
if( n ) {
|
||||
sig->unhashed_data = m_alloc( n + 2 );
|
||||
sig->unhashed_data[0] = n << 8;
|
||||
sig->unhashed_data[1] = n;
|
||||
if( iobuf_read(inp, sig->unhashed_data+2, n ) != n ) {
|
||||
log_error("premature eof while reading unhashed signature data\n");
|
||||
rc = -1;
|
||||
goto leave;
|
||||
}
|
||||
pktlen -= n;
|
||||
}
|
||||
}
|
||||
|
||||
if( pktlen < 5 ) { /* sanity check */
|
||||
log_error("packet(%d) too short\n", pkttype);
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
sig->digest_start[0] = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->digest_start[1] = iobuf_get_noeof(inp); pktlen--;
|
||||
|
||||
if( is_v4 ) { /*extract required informations */
|
||||
const byte *p;
|
||||
p = parse_subpkt( sig->hashed_data, 2 );
|
||||
if( !p )
|
||||
log_error("signature packet without timestamp\n");
|
||||
else
|
||||
sig->timestamp = buffer_to_u32(p);
|
||||
p = parse_subpkt( sig->unhashed_data, 16 );
|
||||
if( !p )
|
||||
log_error("signature packet without keyid\n");
|
||||
else {
|
||||
sig->keyid[0] = buffer_to_u32(p);
|
||||
sig->keyid[1] = buffer_to_u32(p+4);
|
||||
}
|
||||
}
|
||||
|
||||
if( list_mode ) {
|
||||
printf(":signature packet: keyid %08lX%08lX\n"
|
||||
"\tversion %d, created %lu, md5len %d, sigclass %02x\n"
|
||||
"\tdigest algo %d, begin of digest %02x %02x\n",
|
||||
(ulong)sig->keyid[0], (ulong)sig->keyid[1],
|
||||
sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
|
||||
sig->digest_algo,
|
||||
sig->digest_start[0], sig->digest_start[1] );
|
||||
if( is_v4 ) {
|
||||
parse_subpkt( sig->hashed_data, -1 );
|
||||
parse_subpkt( sig->unhashed_data, -2 );
|
||||
}
|
||||
}
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
n = pktlen;
|
||||
sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
n = pktlen;
|
||||
sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( list_mode ) {
|
||||
printf("\tdigest algo %d, begin of digest %02x %02x\n",
|
||||
sig->d.elg.digest_algo,
|
||||
sig->d.elg.digest_start[0], sig->d.elg.digest_start[1] );
|
||||
printf("\telg a: ");
|
||||
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
|
||||
printf("\n\telg b: ");
|
||||
@ -516,20 +688,23 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
if( pktlen < 5 ) {
|
||||
log_error("packet(%d) too short\n", pkttype);
|
||||
goto leave;
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
n = pktlen;
|
||||
sig->d.dsa.r = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
n = pktlen;
|
||||
sig->d.dsa.s = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( list_mode ) {
|
||||
printf("\tdsa r: ");
|
||||
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
|
||||
printf("\n\tdsa s: ");
|
||||
mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
|
||||
putchar('\n');
|
||||
}
|
||||
sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
|
||||
sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
|
||||
}
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
n = pktlen;
|
||||
sig->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( list_mode ) {
|
||||
printf("\tdigest algo %d, begin of digest %02x %02x\n",
|
||||
sig->d.rsa.digest_algo,
|
||||
sig->d.rsa.digest_start[0], sig->d.rsa.digest_start[1] );
|
||||
printf("\trsa integer: ");
|
||||
mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
|
||||
putchar('\n');
|
||||
@ -541,7 +716,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
|
||||
leave:
|
||||
skip_rest(inp, pktlen);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -761,6 +936,137 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
log_mpidump("elg x=", cert->d.elg.x ); */
|
||||
}
|
||||
}
|
||||
else if( algorithm == PUBKEY_ALGO_DSA ) {
|
||||
MPI dsa_p, dsa_q, dsa_g, dsa_y;
|
||||
n = pktlen; dsa_p = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
n = pktlen; dsa_q = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
n = pktlen; dsa_g = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
n = pktlen; dsa_y = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
if( list_mode ) {
|
||||
printf( "\tdsa p: ");
|
||||
mpi_print(stdout, dsa_p, mpi_print_mode );
|
||||
printf("\n\tdsa q: ");
|
||||
mpi_print(stdout, dsa_q, mpi_print_mode );
|
||||
printf("\n\tdsa g: ");
|
||||
mpi_print(stdout, dsa_g, mpi_print_mode );
|
||||
printf("\n\tdsa y: ");
|
||||
mpi_print(stdout, dsa_y, mpi_print_mode );
|
||||
putchar('\n');
|
||||
}
|
||||
if( pkttype == PKT_PUBLIC_CERT ) {
|
||||
pkt->pkt.public_cert->d.dsa.p = dsa_p;
|
||||
pkt->pkt.public_cert->d.dsa.q = dsa_q;
|
||||
pkt->pkt.public_cert->d.dsa.g = dsa_g;
|
||||
pkt->pkt.public_cert->d.dsa.y = dsa_y;
|
||||
}
|
||||
else {
|
||||
PKT_secret_cert *cert = pkt->pkt.secret_cert;
|
||||
byte temp[8];
|
||||
|
||||
pkt->pkt.secret_cert->d.dsa.p = dsa_p;
|
||||
pkt->pkt.secret_cert->d.dsa.q = dsa_q;
|
||||
pkt->pkt.secret_cert->d.dsa.g = dsa_g;
|
||||
pkt->pkt.secret_cert->d.dsa.y = dsa_y;
|
||||
cert->d.dsa.protect.algo = iobuf_get_noeof(inp); pktlen--;
|
||||
if( cert->d.dsa.protect.algo ) {
|
||||
cert->d.dsa.is_protected = 1;
|
||||
cert->d.dsa.protect.count = 0;
|
||||
if( cert->d.dsa.protect.algo == 255 ) {
|
||||
if( pktlen < 3 ) {
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
cert->d.dsa.protect.algo = iobuf_get_noeof(inp); pktlen--;
|
||||
cert->d.dsa.protect.s2k = iobuf_get_noeof(inp); pktlen--;
|
||||
cert->d.dsa.protect.hash = iobuf_get_noeof(inp); pktlen--;
|
||||
switch( cert->d.dsa.protect.s2k ) {
|
||||
case 1:
|
||||
case 3:
|
||||
for(i=0; i < 8 && pktlen; i++, pktlen-- )
|
||||
temp[i] = iobuf_get_noeof(inp);
|
||||
memcpy(cert->d.dsa.protect.salt, temp, 8 );
|
||||
break;
|
||||
}
|
||||
switch( cert->d.dsa.protect.s2k ) {
|
||||
case 0: if( list_mode ) printf( "\tsimple S2K" );
|
||||
break;
|
||||
case 1: if( list_mode ) printf( "\tsalted S2K" );
|
||||
break;
|
||||
case 3: if( list_mode ) printf( "\titer+salt S2K" );
|
||||
break;
|
||||
default:
|
||||
if( list_mode )
|
||||
printf( "\tunknown S2K %d\n",
|
||||
cert->d.dsa.protect.s2k );
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( list_mode ) {
|
||||
printf(", algo: %d, hash: %d",
|
||||
cert->d.dsa.protect.algo,
|
||||
cert->d.dsa.protect.hash );
|
||||
if( cert->d.dsa.protect.s2k == 1
|
||||
|| cert->d.dsa.protect.s2k == 3 ) {
|
||||
printf(", salt: ");
|
||||
for(i=0; i < 8; i++ )
|
||||
printf("%02x", cert->d.dsa.protect.salt[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if( cert->d.dsa.protect.s2k == 3 ) {
|
||||
if( !pktlen ) {
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
cert->d.dsa.protect.count = iobuf_get_noeof(inp);
|
||||
pktlen--;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if( list_mode )
|
||||
printf( "\tprotect algo: %d\n",
|
||||
cert->d.dsa.protect.algo);
|
||||
/* old version, we don't have a S2K, so we fake one */
|
||||
cert->d.dsa.protect.s2k = 0;
|
||||
cert->d.dsa.protect.hash = DIGEST_ALGO_MD5;
|
||||
}
|
||||
if( pktlen < 8 ) {
|
||||
rc = G10ERR_INVALID_PACKET;
|
||||
goto leave;
|
||||
}
|
||||
for(i=0; i < 8 && pktlen; i++, pktlen-- )
|
||||
temp[i] = iobuf_get_noeof(inp);
|
||||
if( list_mode ) {
|
||||
printf( "\tprotect IV: ");
|
||||
for(i=0; i < 8; i++ )
|
||||
printf(" %02x", temp[i] );
|
||||
putchar('\n');
|
||||
}
|
||||
memcpy(cert->d.dsa.protect.iv, temp, 8 );
|
||||
}
|
||||
else
|
||||
cert->d.dsa.is_protected = 0;
|
||||
/* It does not make sense to read it into secure memory.
|
||||
* If the user is so careless, not to protect his secret key,
|
||||
* we can assume, that he operates an open system :=(.
|
||||
* So we put the key into secure memory when we unprotect him. */
|
||||
n = pktlen; cert->d.dsa.x = mpi_read(inp, &n, 0 ); pktlen -=n;
|
||||
|
||||
cert->d.dsa.csum = read_16(inp); pktlen -= 2;
|
||||
if( list_mode ) {
|
||||
printf("\t[secret value x is not shown]\n"
|
||||
"\tchecksum: %04hx\n", cert->d.dsa.csum);
|
||||
}
|
||||
/*log_mpidump("dsa p=", cert->d.dsa.p );
|
||||
log_mpidump("dsa q=", cert->d.dsa.q );
|
||||
log_mpidump("dsa g=", cert->d.dsa.g );
|
||||
log_mpidump("dsa y=", cert->d.dsa.y );
|
||||
log_mpidump("dsa x=", cert->d.dsa.x ); */
|
||||
}
|
||||
}
|
||||
else if( algorithm == PUBKEY_ALGO_RSA ) {
|
||||
MPI rsa_pub_mod, rsa_pub_exp;
|
||||
|
||||
@ -1023,3 +1329,4 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "ttyio.h"
|
||||
#include "filter.h"
|
||||
#include "main.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
/****************
|
||||
@ -58,7 +59,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
||||
fname[pt->namelen] = 0;
|
||||
}
|
||||
|
||||
if( !*fname ) { /* no filename given; write to stdout */
|
||||
if( !*fname || (*fname=='-' && !fname[1])) {
|
||||
/* no filename or "-" given; write to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
else if( overwrite_filep( fname ) )
|
||||
@ -181,3 +183,44 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Hash the given files and append the hash to hash context md.
|
||||
* If FILES is NULL, hash stdin.
|
||||
*/
|
||||
int
|
||||
hash_datafiles( MD_HANDLE md, STRLIST files, int textmode )
|
||||
{
|
||||
IOBUF fp;
|
||||
STRLIST sl=NULL;
|
||||
text_filter_context_t tfx;
|
||||
int c;
|
||||
|
||||
if( !files )
|
||||
add_to_strlist( &sl, "-");
|
||||
else
|
||||
sl = files;
|
||||
|
||||
for( ; sl; sl = sl->next ) {
|
||||
fp = iobuf_open( sl->d );
|
||||
if( !fp ) {
|
||||
log_error(_("can't open signed data '%s'\n"),
|
||||
print_fname_stdin(sl->d));
|
||||
if( !files )
|
||||
free_strlist(sl);
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
if( textmode ) {
|
||||
memset( &tfx, 0, sizeof tfx);
|
||||
iobuf_push_filter( fp, text_filter, &tfx );
|
||||
}
|
||||
while( (c = iobuf_get(fp)) != -1 )
|
||||
md_putc(md, c );
|
||||
iobuf_close(fp);
|
||||
}
|
||||
|
||||
if( !files )
|
||||
free_strlist(sl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -517,6 +517,13 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
&& !mpi_cmp( req_skc->d.elg.y, skc->d.elg.y )
|
||||
&& !mpi_cmp( req_skc->d.elg.x, skc->d.elg.x )
|
||||
)
|
||||
|| ( skc->pubkey_algo == PUBKEY_ALGO_DSA
|
||||
&& !mpi_cmp( req_skc->d.dsa.p, skc->d.dsa.p )
|
||||
&& !mpi_cmp( req_skc->d.dsa.q, skc->d.dsa.q )
|
||||
&& !mpi_cmp( req_skc->d.dsa.g, skc->d.dsa.g )
|
||||
&& !mpi_cmp( req_skc->d.dsa.y, skc->d.dsa.y )
|
||||
&& !mpi_cmp( req_skc->d.dsa.x, skc->d.dsa.x )
|
||||
)
|
||||
|| ( skc->pubkey_algo == PUBKEY_ALGO_RSA
|
||||
&& !mpi_cmp( req_skc->d.rsa.rsa_n, skc->d.rsa.rsa_n )
|
||||
&& !mpi_cmp( req_skc->d.rsa.rsa_e, skc->d.rsa.rsa_e )
|
||||
@ -537,6 +544,12 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname )
|
||||
&& !mpi_cmp( req_pkc->d.elg.g, pkc->d.elg.g )
|
||||
&& !mpi_cmp( req_pkc->d.elg.y, pkc->d.elg.y )
|
||||
)
|
||||
|| ( pkc->pubkey_algo == PUBKEY_ALGO_DSA
|
||||
&& !mpi_cmp( req_pkc->d.dsa.p, pkc->d.dsa.p )
|
||||
&& !mpi_cmp( req_pkc->d.dsa.q, pkc->d.dsa.q )
|
||||
&& !mpi_cmp( req_pkc->d.dsa.g, pkc->d.dsa.g )
|
||||
&& !mpi_cmp( req_pkc->d.dsa.y, pkc->d.dsa.y )
|
||||
)
|
||||
|| ( pkc->pubkey_algo == PUBKEY_ALGO_RSA
|
||||
&& !mpi_cmp( req_pkc->d.rsa.rsa_n, pkc->d.rsa.rsa_n )
|
||||
&& !mpi_cmp( req_pkc->d.rsa.rsa_e, pkc->d.rsa.rsa_e )
|
||||
|
@ -77,9 +77,9 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->d.rsa.digest_algo = digest_algo;
|
||||
sig->d.rsa.digest_start[0] = dp[0];
|
||||
sig->d.rsa.digest_start[1] = dp[1];
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
sig->d.rsa.rsa_integer =
|
||||
encode_md_value( md, mpi_get_nbits(skc->d.rsa.rsa_n));
|
||||
skey.e = skc->d.rsa.rsa_e;
|
||||
|
@ -141,6 +141,7 @@ check_elg( PKT_secret_cert *cert )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
protect_elg( PKT_secret_cert *cert, DEK *dek )
|
||||
{
|
||||
@ -174,6 +175,126 @@ protect_elg( PKT_secret_cert *cert, DEK *dek )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
check_dsa( PKT_secret_cert *cert )
|
||||
{
|
||||
byte *buffer;
|
||||
u16 csum=0;
|
||||
int res;
|
||||
unsigned nbytes;
|
||||
u32 keyid[2];
|
||||
DSA_secret_key skey;
|
||||
char save_iv[8];
|
||||
|
||||
if( cert->d.dsa.is_protected ) { /* remove the protection */
|
||||
DEK *dek = NULL;
|
||||
MPI test_x;
|
||||
BLOWFISH_context *blowfish_ctx=NULL;
|
||||
|
||||
switch( cert->d.dsa.protect.algo ) {
|
||||
case CIPHER_ALGO_NONE: BUG(); break;
|
||||
case CIPHER_ALGO_BLOWFISH:
|
||||
keyid_from_skc( cert, keyid );
|
||||
if( cert->d.dsa.protect.s2k == 1
|
||||
|| cert->d.dsa.protect.s2k == 3 )
|
||||
dek = get_passphrase_hash( keyid, NULL,
|
||||
cert->d.dsa.protect.salt );
|
||||
else
|
||||
dek = get_passphrase_hash( keyid, NULL, NULL );
|
||||
|
||||
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
|
||||
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
|
||||
m_free(dek); /* pw is in secure memory, so m_free() burns it */
|
||||
blowfish_setiv( blowfish_ctx, NULL );
|
||||
memcpy(save_iv, cert->d.dsa.protect.iv, 8 );
|
||||
blowfish_decode_cfb( blowfish_ctx,
|
||||
cert->d.dsa.protect.iv,
|
||||
cert->d.dsa.protect.iv, 8 );
|
||||
mpi_set_secure(cert->d.dsa.x );
|
||||
/*fixme: maybe it is better to set the buffer secure with a
|
||||
* new get_buffer_secure() function */
|
||||
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
|
||||
csum = checksum_u16( nbytes*8 );
|
||||
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes );
|
||||
csum += checksum( buffer, nbytes );
|
||||
test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.dsa.x) );
|
||||
mpi_set_buffer( test_x, buffer, nbytes, 0 );
|
||||
m_free( buffer );
|
||||
m_free( blowfish_ctx );
|
||||
/* now let's see wether we have used the right passphrase */
|
||||
if( csum != cert->d.dsa.csum ) {
|
||||
mpi_free(test_x);
|
||||
memcpy( cert->d.dsa.protect.iv, save_iv, 8 );
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
|
||||
skey.p = cert->d.dsa.p;
|
||||
skey.q = cert->d.dsa.q;
|
||||
skey.g = cert->d.dsa.g;
|
||||
skey.y = cert->d.dsa.y;
|
||||
skey.x = test_x;
|
||||
res = dsa_check_secret_key( &skey );
|
||||
memset( &skey, 0, sizeof skey );
|
||||
if( !res ) {
|
||||
mpi_free(test_x);
|
||||
memcpy( cert->d.dsa.protect.iv, save_iv, 8 );
|
||||
return G10ERR_BAD_PASS;
|
||||
}
|
||||
mpi_set(cert->d.dsa.x, test_x);
|
||||
mpi_free(test_x);
|
||||
cert->d.dsa.is_protected = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
|
||||
}
|
||||
}
|
||||
else { /* not protected */
|
||||
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
|
||||
csum = checksum_u16( nbytes*8 );
|
||||
csum += checksum( buffer, nbytes );
|
||||
m_free( buffer );
|
||||
if( csum != cert->d.dsa.csum )
|
||||
return G10ERR_CHECKSUM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
protect_dsa( PKT_secret_cert *cert, DEK *dek )
|
||||
{
|
||||
byte *buffer;
|
||||
unsigned nbytes;
|
||||
|
||||
if( !cert->d.dsa.is_protected ) { /* add the protection */
|
||||
BLOWFISH_context *blowfish_ctx=NULL;
|
||||
|
||||
switch( cert->d.dsa.protect.algo ) {
|
||||
case CIPHER_ALGO_NONE: BUG(); break;
|
||||
case CIPHER_ALGO_BLOWFISH:
|
||||
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
|
||||
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
|
||||
blowfish_setiv( blowfish_ctx, NULL );
|
||||
blowfish_encode_cfb( blowfish_ctx,
|
||||
cert->d.dsa.protect.iv,
|
||||
cert->d.dsa.protect.iv, 8 );
|
||||
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
|
||||
blowfish_encode_cfb( blowfish_ctx, buffer, buffer, nbytes );
|
||||
mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
|
||||
m_free( buffer );
|
||||
m_free( blowfish_ctx );
|
||||
cert->d.dsa.is_protected = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
static int
|
||||
@ -282,6 +403,8 @@ check_secret_key( PKT_secret_cert *cert )
|
||||
log_error("Invalid passphrase; please try again ...\n");
|
||||
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
rc = check_elg( cert );
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
rc = check_dsa( cert );
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
rc = check_rsa( cert );
|
||||
@ -303,6 +426,8 @@ is_secret_key_protected( PKT_secret_cert *cert )
|
||||
{
|
||||
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
return cert->d.elg.is_protected? cert->d.elg.protect.algo : 0;
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
return cert->d.dsa.is_protected? cert->d.dsa.protect.algo : 0;
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
return cert->d.rsa.is_protected? cert->d.rsa.protect_algo : 0;
|
||||
@ -323,6 +448,8 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek )
|
||||
|
||||
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
return protect_elg( cert, dek );
|
||||
else if( cert->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
return protect_dsa( cert, dek );
|
||||
else
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
}
|
||||
|
@ -66,11 +66,11 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
ELG_public_key pkey;
|
||||
|
||||
if( (rc=check_digest_algo(sig->d.elg.digest_algo)) )
|
||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||
goto leave;
|
||||
/* make sure the digest algo is enabled (in case of a detached
|
||||
* signature */
|
||||
md_enable( digest, sig->d.elg.digest_algo );
|
||||
md_enable( digest, sig->digest_algo );
|
||||
/* complete the digest */
|
||||
md_putc( digest, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
@ -87,6 +87,59 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkey ) )
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||
DSA_public_key pkey;
|
||||
|
||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||
goto leave;
|
||||
/* make sure the digest algo is enabled (in case of a detached
|
||||
* 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 );
|
||||
md_putc( digest, sig->sig_class );
|
||||
if( sig->version < 4 ) {
|
||||
u32 a = sig->timestamp;
|
||||
md_putc( digest, (a >> 24) & 0xff );
|
||||
md_putc( digest, (a >> 16) & 0xff );
|
||||
md_putc( digest, (a >> 8) & 0xff );
|
||||
md_putc( digest, a & 0xff );
|
||||
}
|
||||
else {
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
md_putc( digest, sig->pubkey_algo );
|
||||
md_putc( digest, sig->digest_algo );
|
||||
if( sig->hashed_data ) {
|
||||
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
|
||||
md_write( digest, sig->hashed_data, n+2 );
|
||||
n += 4;
|
||||
}
|
||||
else
|
||||
n = 4;
|
||||
/* add some magic */
|
||||
buf[0] = sig->version;
|
||||
buf[1] = 0xff;
|
||||
buf[2] = n >> 24;
|
||||
buf[3] = n >> 16;
|
||||
buf[4] = n >> 8;
|
||||
buf[5] = n;
|
||||
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));
|
||||
pkey.p = pkc->d.dsa.p;
|
||||
pkey.q = pkc->d.dsa.q;
|
||||
pkey.g = pkc->d.dsa.g;
|
||||
pkey.y = pkc->d.dsa.y;
|
||||
if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkey ) )
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
}
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
int i, j, c, old_enc;
|
||||
@ -125,10 +178,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if( (rc=check_digest_algo(sig->d.rsa.digest_algo)) )
|
||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||
goto leave; /* unsupported algo */
|
||||
md_enable( digest, sig->d.rsa.digest_algo );
|
||||
asn = md_asn_oid( sig->d.rsa.digest_algo, &asnlen, &mdlen );
|
||||
md_enable( digest, sig->digest_algo );
|
||||
asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
|
||||
|
||||
for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
|
||||
i++, j-- )
|
||||
@ -142,7 +195,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
if( c != 0xff )
|
||||
break;
|
||||
i++;
|
||||
if( c != sig->d.rsa.digest_algo || mpi_getbyte(result, i) ) {
|
||||
if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
|
||||
/* Padding or leading bytes in signature is wrong */
|
||||
rc = G10ERR_BAD_PUBKEY;
|
||||
goto leave;
|
||||
@ -163,7 +216,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
md_putc( digest, a & 0xff );
|
||||
}
|
||||
md_final( digest );
|
||||
dp = md_read( digest, sig->d.rsa.digest_algo );
|
||||
dp = md_read( digest, sig->digest_algo );
|
||||
for(i=mdlen-1; i >= 0; i--, dp++ ) {
|
||||
if( mpi_getbyte( result, i ) != *dp ) {
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
@ -188,7 +241,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||
|
||||
/****************
|
||||
* check the signature pointed to by NODE. This is a key signatures.
|
||||
* If the function detects a elf signature, it uses the PKC from
|
||||
* If the function detects a self-signature, it uses the PKC from
|
||||
* NODE and does not read the any public key.
|
||||
*/
|
||||
int
|
||||
@ -210,9 +263,11 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
|
||||
sig = node->pkt->pkt.signature;
|
||||
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
algo = sig->d.elg.digest_algo;
|
||||
algo = sig->digest_algo;
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
algo = sig->digest_algo;
|
||||
else if(sig->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
algo = sig->d.rsa.digest_algo;
|
||||
algo = sig->digest_algo;
|
||||
else
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( (rc=check_digest_algo(algo)) )
|
||||
@ -233,7 +288,18 @@ 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[2] = uid->len >> 16;
|
||||
buf[3] = uid->len >> 8;
|
||||
buf[4] = uid->len;
|
||||
md_write( md, buf, 5 );
|
||||
}
|
||||
md_write( md, uid->name, uid->len );
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
|
||||
if( is_selfsig )
|
||||
@ -243,6 +309,8 @@ 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");
|
||||
|
@ -50,6 +50,8 @@ complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
|
||||
;
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
g10_elg_sign( skc, sig, md, 0 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
g10_dsa_sign( skc, sig, md, 0 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
g10_rsa_sign( skc, sig, md, 0 );
|
||||
else
|
||||
@ -274,6 +276,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
||||
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
g10_dsa_sign( skc, sig, md, DIGEST_ALGO_SHA1 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
|
||||
else
|
||||
@ -428,6 +432,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
||||
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
|
||||
g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_DSA )
|
||||
g10_dsa_sign( skc, sig, md, DIGEST_ALGO_SHA1 );
|
||||
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA )
|
||||
g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 );
|
||||
else
|
||||
@ -1066,6 +1072,7 @@ change_passphrase( const char *username )
|
||||
break;
|
||||
}
|
||||
else { /* okay */
|
||||
/* FIXME: what about dsa */
|
||||
skc->d.elg.protect.algo = CIPHER_ALGO_BLOWFISH;
|
||||
skc->d.elg.protect.s2k = 1;
|
||||
skc->d.elg.protect.hash = DIGEST_ALGO_RMD160;
|
||||
|
16
g10/status.c
16
g10/status.c
@ -36,6 +36,12 @@ set_status_fd( int newfd )
|
||||
|
||||
void
|
||||
write_status( int no )
|
||||
{
|
||||
write_status_text( no, NULL );
|
||||
}
|
||||
|
||||
void
|
||||
write_status_text( int no, const char *text)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
@ -53,7 +59,13 @@ write_status( int no )
|
||||
default: s = "?\n"; break;
|
||||
}
|
||||
|
||||
write( fd, s, strlen(s) );
|
||||
|
||||
if( text ) {
|
||||
write( fd, s, strlen(s)-1 );
|
||||
write( fd, " ", 1 );
|
||||
write( fd, text, strlen(text) );
|
||||
write( fd, "\n", 1 );
|
||||
}
|
||||
else
|
||||
write( fd, s, strlen(s) );
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
/*-- status.c --*/
|
||||
void set_status_fd( int fd );
|
||||
void write_status( int no );
|
||||
void write_status_text( int no, const char *text);
|
||||
|
||||
|
||||
#endif /*G10_STATUS_H*/
|
||||
|
@ -912,7 +912,7 @@ print_user_id( const char *text, u32 *keyid )
|
||||
putchar(' ');
|
||||
}
|
||||
putchar('\"');
|
||||
print_string( stdout, p, n );
|
||||
print_string( stdout, p, n, 0 );
|
||||
putchar('\"');
|
||||
putchar('\n');
|
||||
m_free(p);
|
||||
@ -1520,13 +1520,18 @@ init_trustdb( int level, const char *dbname )
|
||||
assert(p);
|
||||
*p = 0;
|
||||
if( access( fname, F_OK ) ) {
|
||||
#if __MINGW32__
|
||||
if( mkdir( fname ) )
|
||||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
#endif
|
||||
log_fatal("can't create directory '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
if( strlen(fname) >= 7
|
||||
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
|
||||
#if __MINGW32__
|
||||
if( mkdir( fname ) )
|
||||
#else
|
||||
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
|
||||
#endif
|
||||
log_fatal("can't create directory '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
}
|
||||
else
|
||||
log_fatal("directory '%s' does not exist!\n", fname );
|
||||
}
|
||||
*p = '/';
|
||||
create_db( fname );
|
||||
@ -1539,7 +1544,7 @@ init_trustdb( int level, const char *dbname )
|
||||
return 0;
|
||||
|
||||
/* we can verify a signature about our local data (secring and trustdb)
|
||||
* in ~/.g10/ here */
|
||||
* in ~/.gnupg/ here */
|
||||
rc = verify_private_data();
|
||||
if( !rc ) {
|
||||
/* verify, that our own certificates are in the trustDB
|
||||
|
87
g10/verify.c
Normal file
87
g10/verify.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* verify.c - verify signed data
|
||||
* 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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "options.h"
|
||||
#include "packet.h"
|
||||
#include "errors.h"
|
||||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "main.h"
|
||||
#include "filter.h"
|
||||
#include "ttyio.h"
|
||||
#include "i18n.h"
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Assume that the input is a signature and verify it without
|
||||
* generating any output. With no arguments, the sigature packet
|
||||
* is read from stdin (it may be a detached signature when not
|
||||
* used in batch mode). If only a sigfile is given, is maybe a complete
|
||||
* signature or a detached signature in which case the signed stuff
|
||||
* is expected from stdin. With more than 1 argument, the first should
|
||||
* be a detached signature and the remaining files are the signed stuff.
|
||||
*/
|
||||
|
||||
int
|
||||
verify_signatures( int nfiles, char **files )
|
||||
{
|
||||
IOBUF fp;
|
||||
armor_filter_context_t afx;
|
||||
const char *sigfile;
|
||||
int i, rc;
|
||||
STRLIST sl;
|
||||
|
||||
sigfile = nfiles? *files : NULL;
|
||||
|
||||
/* open the signature file */
|
||||
fp = iobuf_open(sigfile);
|
||||
if( !fp ) {
|
||||
log_error(_("can't open '%s'\n"), print_fname_stdin(sigfile));
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
if( !opt.no_armor ) {
|
||||
if( use_armor_filter( fp ) ) {
|
||||
memset( &afx, 0, sizeof afx);
|
||||
iobuf_push_filter( fp, armor_filter, &afx );
|
||||
}
|
||||
}
|
||||
|
||||
sl = NULL;
|
||||
for(i=1 ; i < nfiles; i++ )
|
||||
add_to_strlist( &sl, files[i] );
|
||||
rc = proc_signature_packets( fp, sl );
|
||||
free_strlist(sl);
|
||||
iobuf_close(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
Mon Mar 9 12:59:55 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* cipher.h: Included dsa.h.
|
||||
|
||||
Tue Mar 3 15:11:21 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* cipher.h (random.h): Add new header and move all relevalt
|
||||
functions to this header.
|
||||
|
@ -34,6 +34,8 @@
|
||||
#endif
|
||||
#include "../cipher/blowfish.h"
|
||||
#include "../cipher/elgamal.h"
|
||||
#include "../cipher/dsa.h"
|
||||
#include "../cipher/random.h"
|
||||
|
||||
|
||||
#define CIPHER_ALGO_NONE 0
|
||||
@ -78,10 +80,6 @@ int check_cipher_algo( int algo );
|
||||
int check_pubkey_algo( int algo );
|
||||
int check_digest_algo( int algo );
|
||||
|
||||
/*-- random.c --*/
|
||||
int quick_random_gen( int onoff );
|
||||
void randomize_buffer( byte *buffer, size_t length, int level );
|
||||
byte get_random_byte( int level );
|
||||
|
||||
/*-- smallprime.c --*/
|
||||
extern ushort small_prime_numbers[];
|
||||
|
@ -58,5 +58,6 @@
|
||||
#define G10ERR_CLOSE_FILE 36
|
||||
#define G10ERR_RENAME_FILE 37
|
||||
#define G10ERR_DELETE_FILE 38
|
||||
#define G10ERR_UNEXPECTED 39
|
||||
|
||||
#endif /*G10_ERRORS_H*/
|
||||
|
@ -101,10 +101,13 @@ const char *strusage( int level );
|
||||
|
||||
/*-- fileutil.c --*/
|
||||
char *make_filename( const char *first_part, ... );
|
||||
const char *print_fname_stdin( const char *s );
|
||||
const char *print_fname_stdout( const char *s );
|
||||
|
||||
|
||||
/*-- miscutil.c --*/
|
||||
u32 make_timestamp(void);
|
||||
void print_string( FILE *fp, byte *p, size_t n );
|
||||
void print_string( FILE *fp, byte *p, size_t n, int delim );
|
||||
int answer_is_yes( const char *s );
|
||||
|
||||
/*-- strgutil.c --*/
|
||||
|
@ -1,3 +1,16 @@
|
||||
Sat Mar 7 11:54:35 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* miscutil.c (print_string): New arg delim; changed all callers.
|
||||
|
||||
Thu Mar 5 12:19:30 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* errors.c: New strings.
|
||||
|
||||
Thu Mar 5 12:06:31 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* iobuf.c (iobuf_open): A name of "-" now opens stdin.
|
||||
* fileutil.c (print_fname_stdout, print_fname_stdin): New.
|
||||
|
||||
Fri Feb 27 10:20:03 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* memory.c (m_is_secure): Removed.
|
||||
|
@ -64,9 +64,13 @@ g10_errstr( int err )
|
||||
X(NI_PUBKEY ,"Unimplemented pubkey algorithm")
|
||||
X(NI_CIPHER ,"Unimplemented cipher algorithm")
|
||||
X(SIG_CLASS ,"Unknown signature class")
|
||||
X(TRUSTDB ,"TrustDB error")
|
||||
X(TRUSTDB ,"Trust database error")
|
||||
X(BAD_CERT ,"Bad certificate")
|
||||
X(INV_USER_ID ,"malformed user id")
|
||||
X(INV_USER_ID ,"Malformed user id")
|
||||
X(CLOSE_FILE ,"File close error")
|
||||
X(RENAME_FILE ,"File rename error")
|
||||
X(DELETE_FILE ,"File delete error")
|
||||
X(UNEXPECTED ,"Unexpected data")
|
||||
|
||||
default: p = buf; sprintf(buf, "g10err=%d", err); break;
|
||||
}
|
||||
|
@ -64,3 +64,26 @@ make_filename( const char *first_part, ... )
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* A simple function to decide, wether the filename ist stdout
|
||||
* or a real filename.
|
||||
*/
|
||||
const char *
|
||||
print_fname_stdout( const char *s )
|
||||
{
|
||||
if( !s || (*s == '-' && !s[1]) )
|
||||
return "[stdout]";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
print_fname_stdin( const char *s )
|
||||
{
|
||||
if( !s || (*s == '-' && !s[1]) )
|
||||
return "[stdin]";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,7 +371,7 @@ iobuf_open( const char *fname )
|
||||
file_filter_ctx_t *fcx;
|
||||
size_t len;
|
||||
|
||||
if( !fname ) {
|
||||
if( !fname || (*fname=='-' && !fname[1]) ) {
|
||||
fp = stdin; /* fixme: set binary mode for msdoze */
|
||||
fname = "[stdin]";
|
||||
}
|
||||
|
@ -37,13 +37,21 @@ make_timestamp()
|
||||
* Print a string to FP, but filter all control characters out.
|
||||
*/
|
||||
void
|
||||
print_string( FILE *fp, byte *p, size_t n )
|
||||
print_string( FILE *fp, byte *p, size_t n, int delim )
|
||||
{
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
if( iscntrl( *p ) || *p == delim ) {
|
||||
putc('\\', fp);
|
||||
if( *p == '\n' )
|
||||
putc('n', fp);
|
||||
else if( *p == '\r' )
|
||||
putc('r', fp);
|
||||
else if( *p == '\f' )
|
||||
putc('f', fp);
|
||||
else if( *p == '\v' )
|
||||
putc('v', fp);
|
||||
else if( *p == '\b' )
|
||||
putc('b', fp);
|
||||
else if( !*p )
|
||||
putc('0', fp);
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user