aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog32
-rw-r--r--g10/OPTIONS13
-rw-r--r--g10/armor.c27
-rw-r--r--g10/g10.c32
-rw-r--r--g10/getkey.c4
-rw-r--r--g10/keydb.h8
-rw-r--r--g10/keyedit.c4
-rw-r--r--g10/keygen.c6
-rw-r--r--g10/keyid.c24
-rw-r--r--g10/keylist.c4
-rw-r--r--g10/main.h4
-rw-r--r--g10/mainproc.c27
-rw-r--r--g10/misc.c22
-rw-r--r--g10/openfile.c2
-rw-r--r--g10/options.h1
-rw-r--r--g10/packet.h2
-rw-r--r--g10/pkclist.c8
-rw-r--r--g10/plaintext.c45
-rw-r--r--g10/seskey.c1
-rw-r--r--g10/sign.c2
-rw-r--r--g10/tdbio.c234
-rw-r--r--g10/tdbio.h70
-rw-r--r--g10/trustdb.c255
-rw-r--r--g10/verify.c2
24 files changed, 547 insertions, 282 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index a637ac9e9..f6f935a57 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,35 @@
+Tue Jul 14 18:09:51 1998 Werner Koch ([email protected])
+
+ * keyid.c (fingerprint_from_pk): Add argument and changed all callers.
+ (fingerprint_from_sk): Ditto.
+
+Tue Jul 14 10:10:03 1998 Werner Koch ([email protected])
+
+ * plaintext.c (handle_plaintext): Now returns create error if
+ the file could not be created or the user responded not to overwrite
+ the file.
+ * mainproc.c (proc_plaintext): Tries again if the file could not
+ be created to check the signature without output.
+
+ * misc.c (disable_core_dumps): New.
+ * g10.c (main): disable coredumps for gpg
+
+ * g10.c (MAINTAINER_OPTIONS): New to disable some options
+
+Mon Jul 13 16:47:54 1998 Werner Koch ([email protected])
+
+ * plaintext.c (hash_datafiles): New arg for better support of
+ detached sigs. Changed all callers.
+ * mainproc.c (proc_signature_packets): Ditto.
+
+ * g10.c (main): New option "compress-sigs"
+ * sig.c (sign_file): detached signatures are not anymore compressed
+ unless the option --compress-sigs is used.
+
+Thu Jul 9 19:54:54 1998 Werner Koch ([email protected])
+
+ * armor.c: Fixes to allow zero length cleartext signatures
+
Thu Jul 9 14:52:47 1998 Werner Koch ([email protected])
* g10.c (build_list): Now drops setuid.
diff --git a/g10/OPTIONS b/g10/OPTIONS
index 3abe296d8..8e9cf8a6c 100644
--- a/g10/OPTIONS
+++ b/g10/OPTIONS
@@ -17,15 +17,7 @@
#-----------------------------------------------
#------------------- Commands ------------------
#-----------------------------------------------
-# With some expections, these cannot be combined
-
-gen-prime
-# Generate a prime.
-# With one argument: take it as the bitsize and make a simple prime of
-# this size
-# With two arguments: Generate a prime, usable for DL algorithms.
-# With three arguments: same as above, but a third argument indicates
-# that a generator should also be calculated.
+# With some exceptions, these cannot be combined
print-md algo
# print the message digest of algorithm ALGO for stdin or all
@@ -53,4 +45,7 @@ compress-keys
# algorithm with --compress-algo" - Default is to not compress keys, as
# this is better for interoperability.
+compress-sigs
+# Normally, compressing of signatures does not make sense; so this
+# is disabled for detached signatures unless this option is used.
diff --git a/g10/armor.c b/g10/armor.c
index 46151eae8..45f962f01 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -62,6 +62,7 @@ typedef enum {
fhdrSKIPHeader,
fhdrCLEARSIG,
fhdrREADClearsig,
+ fhdrNullClearsig,
fhdrEMPTYClearsig,
fhdrCHECKClearsig,
fhdrCHECKClearsig2,
@@ -343,6 +344,8 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
*r_hashes |= hashes;
}
}
+ else if( clearsig && n > 15 && !memcmp(buf, "-----", 5 ) )
+ state = fhdrNullClearsig;
else
state = fhdrCHECKDashEscaped3;
}
@@ -386,7 +389,10 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
buf[n++] = c;
if( n < buflen || c == '\n' ) {
buf[n] = 0;
- state = fhdrCHECKDashEscaped3;
+ if( n > 15 && !memcmp(buf, "-----", 5 ) )
+ state = fhdrNullClearsig;
+ else
+ state = fhdrCHECKDashEscaped3;
}
else {
/* fixme: we should check whether this line continues
@@ -396,6 +402,10 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
}
break;
+ case fhdrNullClearsig: /* zero length cleartext */
+ state = fhdrENDClearsig;
+ break;
+
case fhdrENDClearsig:
case fhdrCHECKBegin:
state = state == fhdrCHECKBegin ? fhdrINITSkip : fhdrERRORShow;
@@ -587,10 +597,8 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
buf[1] = '\n';
n = 2;
}
-
}
-
*r_buflen = n;
*r_empty = empty;
return state;
@@ -627,6 +635,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
rc = -1;
break;
+ case fhdrNullClearsig:
case fhdrCLEARSIG: /* start fake package mode (for clear signatures) */
afx->helplen = n;
afx->helpidx = 0;
@@ -679,7 +688,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
rc = -1;
continue;
}
- if( afx->helpidx < afx->helplen ) { /* flush the last buffer */
+ if( state != fhdrNullClearsig
+ && afx->helpidx < afx->helplen ) { /* flush the last buffer */
n = afx->helplen;
for(nn=afx->helpidx; len < size && nn < n ; nn++ )
buf[len++] = afx->helpbuf[nn];
@@ -693,7 +703,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
/* read a new one */
n = DIM(afx->helpbuf);
afx->helpidx = 0;
- state = find_header( state, afx->helpbuf, &n, a, 0,
+ state = find_header( state, afx->helpbuf, &n, a,
+ state == fhdrNullClearsig? afx->helplen:0,
&emplines, &afx->hashes );
switch( state) {
case fhdrERROR:
@@ -723,8 +734,10 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
buf[0] = (len-2) >> 8;
buf[1] = (len-2);
if( state == fhdrENDClearsig ) { /* write last (ending) length header */
- buf[len++] = 0;
- buf[len++] = 0;
+ if( buf[0] || buf[1] ) { /* write only if length of text is > 0 */
+ buf[len++] = 0;
+ buf[len++] = 0;
+ }
rc = 0;
}
diff --git a/g10/g10.c b/g10/g10.c
index 8082fe2eb..308b58227 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
+/* #define MAINTAINER_OPTIONS */
#include "packet.h"
#include "iobuf.h"
@@ -85,8 +86,10 @@ static ARGPARSE_OPTS opts[] = {
{ 547, "enarmor", 0, N_("En-Armor a file or stdin") },
{ 555, "print-md" , 0, N_("|algo [files]|print message digests")},
{ 516, "print-mds" , 0, N_("print all message digests")},
+ #ifdef MAINTAINER_OPTIONS
{ 513, "gen-prime" , 0, "@" },
{ 548, "gen-random" , 0, "@" },
+ #endif
#endif
{ 301, NULL, 0, N_("@\nOptions:\n ") },
@@ -165,6 +168,7 @@ static ARGPARSE_OPTS opts[] = {
{ 508, "check-sig",0, "@" }, /* alias */
{ 553, "skip-verify",0, "@" },
{ 557, "compress-keys",0, "@"},
+ { 566, "compress-sigs",0, "@"},
{ 559, "always-trust", 0, "@"},
{ 562, "emulate-checksum-bug", 0, "@"},
@@ -413,6 +417,7 @@ main( int argc, char **argv )
*/
log_set_name("gpg");
secure_random_alloc(); /* put random number into secure memory */
+ disable_core_dumps();
init_signals();
#endif
i18n_init();
@@ -529,15 +534,17 @@ main( int argc, char **argv )
#endif /* !IS_G10 */
#ifdef IS_G10MAINT
- case 513: set_cmd( &cmd, aPrimegen); break;
- case 514: set_cmd( &cmd, aTest); break;
+ #ifdef MAINTAINER_OPTIONS
+ case 513: set_cmd( &cmd, aPrimegen); break;
+ case 514: set_cmd( &cmd, aTest); break;
+ case 548: set_cmd( &cmd, aGenRandom); break;
+ #endif
case 516: set_cmd( &cmd, aPrintMDs); break;
case 531: set_cmd( &cmd, aListTrustDB); break;
case 533: set_cmd( &cmd, aListTrustPath); break;
case 540: break; /* dummy */
case 546: set_cmd( &cmd, aDeArmor); break;
case 547: set_cmd( &cmd, aEnArmor); break;
- case 548: set_cmd( &cmd, aGenRandom); break;
case 555: set_cmd( &cmd, aPrintMD); break;
case 564: set_cmd( &cmd, aListOwnerTrust); break;
#endif /* IS_G10MAINT */
@@ -596,6 +603,7 @@ main( int argc, char **argv )
case 562: opt.emulate_bugs |= 1; break;
case 563: set_cmd( &cmd, aExportSecret); break;
case 565: opt.do_not_export_rsa = 1; break;
+ case 566: opt.compress_sigs = 1; break;
default : errors++; pargs.err = configfp? 1:2; break;
}
}
@@ -725,16 +733,16 @@ main( int argc, char **argv )
if( argc > 1 )
wrong_args(_("--store [filename]"));
if( (rc = encode_store(fname)) )
- log_error("%s: store failed: %s\n",
- print_fname_stdin(fname), g10_errstr(rc) );
+ log_error_f( print_fname_stdin(fname),
+ "store failed: %s\n", 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",
- print_fname_stdin(fname), g10_errstr(rc) );
+ log_error_f(print_fname_stdin(fname),
+ "symmetric encryption failed: %s\n",g10_errstr(rc) );
break;
case aEncr: /* encrypt the given file */
@@ -933,6 +941,7 @@ main( int argc, char **argv )
break;
+ #ifdef MAINTAINER_OPTIONS
case aPrimegen:
if( argc == 1 ) {
mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
@@ -960,7 +969,9 @@ main( int argc, char **argv )
else
usage(1);
break;
+ #endif /* MAINTAINER OPTIONS */
+ #ifdef MAINTAINER_OPTIONS
case aGenRandom:
if( argc < 1 || argc > 2 )
wrong_args("--gen-random level [hex]");
@@ -977,6 +988,7 @@ main( int argc, char **argv )
}
}
break;
+ #endif /* MAINTAINER OPTIONS */
case aPrintMD:
if( argc < 1)
@@ -1007,7 +1019,9 @@ main( int argc, char **argv )
}
break;
+ #ifdef MAINTAINER_OPTIONS
case aTest: do_test( argc? atoi(*argv): 1 ); break;
+ #endif /* MAINTAINER OPTIONS */
case aListTrustDB:
if( !argc )
@@ -1085,7 +1099,7 @@ do_not_use_RSA()
if( !did_rsa_note ) {
did_rsa_note = 1;
- log_info(_("RSA keys are depreciated; please consider "
+ log_info(_("RSA keys are deprecated; please consider "
"creating a new key and use this key in the future\n"));
}
}
@@ -1194,10 +1208,12 @@ print_mds( const char *fname, int algo )
+#ifdef MAINTAINER_OPTIONS
static void
do_test(int times)
{
m_check(NULL);
}
+#endif /* MAINTAINER OPTIONS */
#endif /* IS_G10MAINT */
diff --git a/g10/getkey.c b/g10/getkey.c
index 3f8ac63b8..b73a00616 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -758,7 +758,7 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
else if( mode == 16 || mode == 20 ) {
size_t an;
byte *afp = fingerprint_from_pk(
- k->pkt->pkt.public_key, &an );
+ k->pkt->pkt.public_key, NULL, &an );
if( DBG_CACHE ) {
u32 aki[2];
@@ -897,7 +897,7 @@ lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name )
else if( mode == 16 || mode == 20 ) {
size_t an;
byte *afp = fingerprint_from_sk(
- k->pkt->pkt.secret_key, &an );
+ k->pkt->pkt.secret_key, NULL, &an );
if( an == mode && !memcmp( afp, name, an)
&& ( !sk->pubkey_algo
|| sk->pubkey_algo
diff --git a/g10/keydb.h b/g10/keydb.h
index 58a170d27..a0398092a 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -25,6 +25,7 @@
#include "packet.h"
#include "cipher.h"
+#define MAX_FINGERPRINT_LEN 20
/****************
@@ -80,11 +81,12 @@ struct pubkey_find_info {
u32 keyid[2];
unsigned nbits;
byte pubkey_algo;
- byte fingerprint[20];
+ byte fingerprint[MAX_FINGERPRINT_LEN];
char userid[1];
};
+
/*-- pkclist.c --*/
int check_signatures_trust( PKT_signature *sig );
void release_pk_list( PK_LIST pk_list );
@@ -128,8 +130,8 @@ unsigned nbits_from_sk( PKT_secret_key *sk );
const char *datestr_from_pk( PKT_public_key *pk );
const char *datestr_from_sk( PKT_secret_key *sk );
const char *datestr_from_sig( PKT_signature *sig );
-byte *fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len );
-byte *fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len );
+byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf. size_t *ret_len );
+byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
/*-- kbnode.c --*/
KBNODE new_kbnode( PACKET *pkt );
diff --git a/g10/keyedit.c b/g10/keyedit.c
index ee50a7880..4369e9a86 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -45,7 +45,7 @@ show_fingerprint( PKT_public_key *pk )
byte *array, *p;
size_t i, n;
- p = array = fingerprint_from_pk( pk, &n );
+ p = array = fingerprint_from_pk( pk, NULL, &n );
tty_printf(" Fingerprint:");
if( n == 20 ) {
for(i=0; i < n ; i++, i++, p += 2 ) {
@@ -292,7 +292,7 @@ sign_key( const char *username, STRLIST locusr )
if( !opt.batch ) {
/* ask whether we really should do anything */
answer = tty_get(
- _("To you want to remove some of the invalid sigs? "));
+ _("Do you want to remove some of the invalid signatures? "));
tty_kill_prompt();
if( answer_is_yes(answer) )
remove_keysigs( keyblock, pk_keyid, 0 );
diff --git a/g10/keygen.c b/g10/keygen.c
index d9f8579e4..b114b8444 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -442,9 +442,9 @@ ask_keysize( int algo )
else if( nbits < 768 )
tty_printf(_("keysize too small; 768 is smallest value allowed.\n"));
else if( nbits > 2048 ) {
- tty_printf(_("Keysizes larger than 2048 are not suggested, because "
+ tty_printf(_("Keysizes larger than 2048 are not suggested because "
"computations take REALLY long!\n"));
- answer = tty_get(_("Are you sure, that you want this keysize? "));
+ answer = tty_get(_("Are you sure that you want this keysize? "));
tty_kill_prompt();
if( answer_is_yes(answer) ) {
m_free(answer);
@@ -685,7 +685,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
tty_printf(_(
"You don't want a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at any time,\n"
- "using this program with the option \"--change-passphrase\"\n\n"));
+ "using this program with the option \"--change-passphrase\".\n\n"));
break;
}
else
diff --git a/g10/keyid.c b/g10/keyid.c
index 0809df93a..2e5c6aad6 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -262,13 +262,13 @@ datestr_from_sig( PKT_signature *sig )
/**************** .
* Return a byte array with the fingerprint for the given PK/SK
* The length of the array is returned in ret_len. Caller must free
- * the array.
+ * the array or provide array as buffer of length MAX_FINGERPRINT_LEN
*/
byte *
-fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
+fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
{
- byte *p, *buf, *array;
+ byte *p, *buf;
const char *dp;
size_t len;
unsigned n;
@@ -287,7 +287,8 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
m_free(buf);
}
md_final(md);
- array = m_alloc( 16 );
+ if( !array )
+ array = m_alloc( 16 );
len = 16;
memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
md_close(md);
@@ -297,7 +298,9 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
md = do_fingerprint_md(pk);
dp = md_read( md, 0 );
len = md_digest_length( md_get_algo( md ) );
- array = m_alloc( len );
+ assert( len <= MAX_FINGERPRINT_LEN );
+ if( !array )
+ array = m_alloc( len );
memcpy(array, dp, len );
md_close(md);
}
@@ -307,9 +310,9 @@ fingerprint_from_pk( PKT_public_key *pk, size_t *ret_len )
}
byte *
-fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
+fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
{
- byte *p, *buf, *array;
+ byte *p, *buf;
const char *dp;
size_t len;
unsigned n;
@@ -328,7 +331,8 @@ fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
m_free(buf);
}
md_final(md);
- array = m_alloc( 16 );
+ if( !array )
+ array = m_alloc( 16 );
len = 16;
memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
md_close(md);
@@ -338,7 +342,9 @@ fingerprint_from_sk( PKT_secret_key *sk, size_t *ret_len )
md = do_fingerprint_md_sk(sk);
dp = md_read( md, 0 );
len = md_digest_length( md_get_algo( md ) );
- array = m_alloc( len );
+ assert( len <= MAX_FINGERPRINT_LEN );
+ if( !array )
+ array = m_alloc( len );
memcpy(array, dp, len );
md_close(md);
}
diff --git a/g10/keylist.c b/g10/keylist.c
index f06b4989f..d23a98f1e 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -339,8 +339,8 @@ fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
byte *array, *p;
size_t i, n;
- p = array = pk? fingerprint_from_pk( pk, &n )
- : fingerprint_from_sk( sk, &n );
+ p = array = pk? fingerprint_from_pk( pk, NULL, &n )
+ : fingerprint_from_sk( sk, NULL, &n );
if( opt.with_colons ) {
printf("fpr:::::::::");
for(i=0; i < n ; i++, p++ )
diff --git a/g10/main.h b/g10/main.h
index dcba0488f..fdb01343f 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -47,6 +47,7 @@ void do_not_use_RSA(void);
/*-- misc.c --*/
void trap_unaligned(void);
+void disable_core_dumps(void);
u16 checksum_u16( unsigned n );
u16 checksum( byte *p, unsigned n );
u16 checksum_mpi( MPI a );
@@ -119,7 +120,8 @@ int verify_signatures( int nfiles, char **files );
int decrypt_message( const char *filename );
/*-- plaintext.c --*/
-int hash_datafiles( MD_HANDLE md, STRLIST files, int textmode );
+int hash_datafiles( MD_HANDLE md, STRLIST files, const char *sigfilename,
+ int textmode );
/*-- signal.c --*/
void init_signals(void);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 9090fd4e1..cd3e85a8b 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -51,6 +51,7 @@ typedef struct {
int sigs_only; /* process only signatures and reject all other stuff */
int encrypt_only; /* process only encrytion messages */
STRLIST signed_data;
+ const char *sigfilename;
DEK *dek;
int last_was_session_key;
KBNODE list; /* the current list of packets */
@@ -262,7 +263,7 @@ proc_plaintext( CTX c, PACKET *pkt )
clearsig = 1;
}
}
- if( !any ) { /* no onepass sig packet: enable all algos */
+ if( !any ) { /* no onepass sig packet: enable all standard algos */
md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
@@ -273,13 +274,13 @@ proc_plaintext( CTX c, PACKET *pkt )
m_check( c->mfx.md->list );
}
rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
+ if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
+ /* can't write output but we hash it anyway to
+ * check the signature */
+ rc = handle_plaintext( pt, &c->mfx, 1, clearsig );
+ }
if( rc )
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
- if( c->mfx.md ) {
- m_check(c->mfx.md);
- if( c->mfx.md->list )
- m_check( c->mfx.md->list );
- }
free_packet(pkt);
c->last_was_session_key = 0;
}
@@ -288,7 +289,8 @@ proc_plaintext( CTX c, PACKET *pkt )
static int
proc_compressed_cb( IOBUF a, void *info )
{
- return proc_signature_packets( a, ((CTX)info)->signed_data );
+ return proc_signature_packets( a, ((CTX)info)->signed_data,
+ ((CTX)info)->sigfilename );
}
static int
@@ -405,8 +407,8 @@ print_fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
byte *array, *p;
size_t i, n;
- p = array = sk? fingerprint_from_sk( sk, &n )
- : fingerprint_from_pk( pk, &n );
+ p = array = sk? fingerprint_from_sk( sk, NULL, &n )
+ : fingerprint_from_pk( pk, NULL, &n );
if( opt.with_colons ) {
printf("fpr:::::::::");
for(i=0; i < n ; i++, p++ )
@@ -665,12 +667,13 @@ proc_packets( IOBUF a )
}
int
-proc_signature_packets( IOBUF a, STRLIST signedfiles )
+proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfilename )
{
CTX c = m_alloc_clear( sizeof *c );
int rc;
c->sigs_only = 1;
c->signed_data = signedfiles;
+ c->sigfilename = sigfilename;
rc = do_proc_packets( c, a );
m_free( c );
return rc;
@@ -881,7 +884,7 @@ proc_tree( CTX c, KBNODE node )
}
/* ask for file and hash it */
if( c->sigs_only )
- rc = hash_datafiles( c->mfx.md, c->signed_data,
+ rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
n1->pkt->pkt.onepass_sig->sig_class == 0x01 );
else
rc = ask_for_detached_datafile( &c->mfx,
@@ -902,7 +905,7 @@ proc_tree( CTX c, KBNODE node )
free_md_filter_context( &c->mfx );
c->mfx.md = md_open(sig->digest_algo, 0);
if( c->sigs_only )
- rc = hash_datafiles( c->mfx.md, c->signed_data,
+ rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
sig->sig_class == 0x01 );
else
rc = ask_for_detached_datafile( &c->mfx,
diff --git a/g10/misc.c b/g10/misc.c
index 470307363..ec7c40a1a 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -22,10 +22,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#if defined(__linux__) && defined(__alpha__)
#include <asm/sysinfo.h>
#include <asm/unistd.h>
#endif
+#ifdef HAVE_SETRLIMIT
+ #include <sys/time.h>
+ #include <sys/resource.h>
+#endif
#include "util.h"
#include "main.h"
#include "options.h"
@@ -70,6 +75,23 @@ trap_unaligned(void)
#endif
+void
+disable_core_dumps()
+{
+ #ifdef HAVE_SETRLIMIT
+ struct rlimit limit;
+
+ limit.rlim_cur = 0;
+ limit.rlim_max = 0;
+ if( setrlimit( RLIMIT_CORE, &limit ) )
+ log_fatal("can't disable core dumps: %s\n", strerror(errno) );
+ #else
+ log_info("WARNING: Program may create a core file!\n");
+ #endif
+}
+
+
+
u16
checksum_u16( unsigned n )
{
diff --git a/g10/openfile.c b/g10/openfile.c
index be2702b55..afa36b983 100644
--- a/g10/openfile.c
+++ b/g10/openfile.c
@@ -142,6 +142,8 @@ open_sigfile( const char *iname )
buf = m_strdup(iname);
buf[len-4] = 0 ;
a = iobuf_open( buf );
+ if( opt.verbose )
+ log_info("assuming signed data in '%s'\n", buf );
m_free(buf);
}
}
diff --git a/g10/options.h b/g10/options.h
index 0929be328..80a6539ec 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -47,6 +47,7 @@ struct {
const char *homedir;
int skip_verify;
int compress_keys;
+ int compress_sigs;
int always_trust;
int rfc1991;
unsigned emulate_bugs; /* bug emulation flags */
diff --git a/g10/packet.h b/g10/packet.h
index 0cefd8d10..cef9afe5c 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -222,7 +222,7 @@ typedef enum {
/*-- mainproc.c --*/
int proc_packets( IOBUF a );
-int proc_signature_packets( IOBUF a, STRLIST signedfiles );
+int proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfile );
int proc_encryption_packets( IOBUF a );
int list_packets( IOBUF a );
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 81e23c765..e509f0064 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -63,7 +63,7 @@ query_ownertrust( ulong lid )
return 0;
}
- tty_printf(_("No ownertrust defined for %lu:\n"
+ tty_printf(_("No owner trust defined for %lu:\n"
"%4u%c/%08lX %s \""), lid,
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk( pk ) );
@@ -143,7 +143,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
while( !(rc=enum_trust_web( &context, &lid )) ) {
rc = get_ownertrust( lid, &trust );
if( rc )
- log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
+ log_fatal("Ooops: couldn't get owner trust for %lu\n", lid);
if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
trust == TRUST_UNKNOWN ) {
if( query_ownertrust( lid ) )
@@ -155,7 +155,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
enum_trust_web( &context, NULL ); /* close */
if( !any )
- tty_printf(_("No ownertrust values changed.\n\n") );
+ tty_printf(_("No owner trust values changed.\n\n") );
return rc? rc : any? 0:-1;
}
@@ -366,7 +366,7 @@ check_signatures_trust( PKT_signature *sig )
case TRUST_MARGINAL:
write_status( STATUS_TRUST_MARGINAL );
log_info(_(
- "WARNING: This key is not certified with enough trusted signatures!\n"
+ "WARNING: This key is not certified with sufficiently trusted signatures!\n"
));
log_info(_(
" It is not certain that the signature belongs to the owner.\n"
diff --git a/g10/plaintext.c b/g10/plaintext.c
index 8d7b2a97e..1a22ecdbd 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -109,14 +109,17 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
/* no filename or "-" given; write to stdout */
fp = stdout;
}
- else if( overwrite_filep( fname ) )
+ else if( (rc=overwrite_filep( fname )) ) {
+ if( rc == -1 )
+ rc = G10ERR_CREATE_FILE;
goto leave;
+ }
if( fp || nooutput )
;
else if( !(fp = fopen(fname,"wb")) ) {
log_error("Error creating '%s': %s\n", fname, strerror(errno) );
- rc = G10ERR_WRITE_FILE;
+ rc = G10ERR_CREATE_FILE;
goto leave;
}
@@ -245,20 +248,43 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
}
+static void
+do_hash( MD_HANDLE md, IOBUF fp, int textmode )
+{
+ text_filter_context_t tfx;
+ int c;
+
+ if( textmode ) {
+ memset( &tfx, 0, sizeof tfx);
+ iobuf_push_filter( fp, text_filter, &tfx );
+ }
+ while( (c = iobuf_get(fp)) != -1 )
+ md_putc(md, c );
+}
+
+
/****************
* 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 )
+hash_datafiles( MD_HANDLE md, STRLIST files,
+ const char *sigfilename, int textmode )
{
IOBUF fp;
STRLIST sl=NULL;
- text_filter_context_t tfx;
- int c;
- if( !files )
+ if( !files ) {
+ /* check whether we can opne the signed material */
+ fp = open_sigfile( sigfilename );
+ if( fp ) {
+ do_hash( md, fp, textmode );
+ iobuf_close(fp);
+ return 0;
+ }
+ /* no we can't (no sigfile) - read signed stuff from stdin */
add_to_strlist( &sl, "-");
+ }
else
sl = files;
@@ -271,12 +297,7 @@ hash_datafiles( MD_HANDLE md, STRLIST files, int textmode )
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 );
+ do_hash( md, fp, textmode );
iobuf_close(fp);
}
diff --git a/g10/seskey.c b/g10/seskey.c
index 5b271a2d4..6e76d12db 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -86,6 +86,7 @@ encode_session_key( DEK *dek, unsigned nbits )
frame[n++] = 2;
i = nframe - 6 - dek->keylen;
assert( i > 0 );
+ /* FIXME: replace the loop by a call to get_random_bits() */
for( ; i ; i-- ) {
while( !(c = get_random_byte(1)) )
;
diff --git a/g10/sign.c b/g10/sign.c
index 14dfe417e..6192d5987 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -226,7 +226,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
iobuf_push_filter( out, encrypt_filter, &efx );
}
- if( opt.compress && !outfile ) {
+ if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
if( old_style )
zfx.algo = 1;
iobuf_push_filter( out, compress_filter, &zfx );
diff --git a/g10/tdbio.c b/g10/tdbio.c
index d3b9a7221..425e51cbb 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -147,7 +147,7 @@ create_db( const char *fname )
fp =fopen( fname, "w" );
if( !fp )
log_fatal_f( fname, _("can't create %s: %s\n"), strerror(errno) );
- fwrite_8( fp, 1 );
+ fwrite_8( fp, 2 );
fwrite_8( fp, 'g' );
fwrite_8( fp, 'p' );
fwrite_8( fp, 'g' );
@@ -195,55 +195,67 @@ tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
case RECTYPE_VER: fprintf(fp, "version\n");
break;
case RECTYPE_DIR:
- fprintf(fp, "dir keyid=%08lX, key=%lu, ctl=%lu, sig=%lu",
- (ulong)rec->r.dir.keyid[1],
- rec->r.dir.keyrec, rec->r.dir.ctlrec, rec->r.dir.sigrec );
- if( rec->r.dir.no_sigs == 1 )
+ fprintf(fp, "dir %lu, keys=%lu, uids=%lu, cach=%lu, ot=%02x",
+ rec->r.dir.lid,
+ rec->r.dir.keylist,
+ rec->r.dir.uidlist,
+ rec->r.dir.cacherec,
+ rec->r.dir.ownertrust );
+ if( rec->r.dir.sigflag == 1 )
fputs(", (none)", fp );
- else if( rec->r.dir.no_sigs == 2 )
+ else if( rec->r.dir.sigflag == 2 )
fputs(", (invalid)", fp );
- else if( rec->r.dir.no_sigs == 3 )
+ else if( rec->r.dir.sigflag == 3 )
fputs(", (revoked)", fp );
- else if( rec->r.dir.no_sigs )
+ else if( rec->r.dir.sigflag )
fputs(", (??)", fp );
putc('\n', fp);
break;
- case RECTYPE_KEY: fprintf(fp,
- "key %08lX, own=%lu, ownertrust=%02x, fl=%d\n",
- (ulong)rec->r.key.keyid[1],
- rec->r.key.owner, rec->r.key.ownertrust,
+ case RECTYPE_KEY:
+ fprintf(fp, "key %lu, next=%lu, algo=%d, flen=%d\n",
+ rec->r.key.lid,
+ rec->r.key.next,
+ rec->r.key.pubkey_algo,
rec->r.key.fingerprint_len );
break;
case RECTYPE_UID:
- if( !rec->r.uid.subtype )
- fprintf(fp,
- "uid %02x%02x, owner=%lu, chain=%lu, pref=%lu, otr=%02x\n",
- rec->r.uid.namehash[18], rec->r.uid.namehash[19],
- rec->r.uid.owner, rec->r.uid.chain, (ulong)rec->r.uid.prefrec,
- rec->r.uid.ownertrust );
- else
- fprintf(fp,
- "uid subtype%d, owner=%lu, chain=%lu\n",
- rec->r.uid.subtype, rec->r.uid.owner, rec->r.uid.chain);
+ fprintf(fp, "uid %lu, next=%lu, pref=%lu, sig=%lu, hash=%02X%02X\n",
+ rec->r.uid.lid,
+ rec->r.uid.next,
+ rec->r.uid.prefrec,
+ rec->r.uid.siglist,
+ rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
break;
- case RECTYPE_CTL: fprintf(fp, "ctl\n");
+ case RECTYPE_PREF:
+ fprintf(fp, "pref %lu, next=%lu\n",
+ rec->r.uid.lid,
+ rec->r.uid.next);
break;
case RECTYPE_SIG:
- fprintf(fp, "sigrec, owner=%lu, chain=%lu\n",
- rec->r.sig.owner, rec->r.sig.chain );
+ fprintf(fp, "sig %lu, next=%lu\n",
+ rec->r.sig.lid, rec->r.sig.next );
for(i=any=0; i < SIGS_PER_RECORD; i++ ) {
- if( rec->r.sig.sig[i].local_id ) {
+ if( rec->r.sig.sig[i].lid ) {
if( !any ) {
putc('\t', fp);
any++;
}
- fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].local_id,
- rec->r.sig.sig[i].flag );
+ fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].lid,
+ rec->r.sig.sig[i].flag );
}
}
if( any )
putc('\n', fp);
break;
+ case RECTYPE_CACH:
+ fprintf(fp, "cach\n");
+ break;
+ case RECTYPE_HTBL:
+ fprintf(fp, "htbl\n");
+ break;
+ case RECTYPE_HTBL:
+ fprintf(fp, "hlst\n");
+ break;
default:
fprintf(fp, "%d (unknown)\n", rec->rectype );
break;
@@ -287,8 +299,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
case 0: /* unused record */
break;
case RECTYPE_VER: /* version record */
- /* g10 was the original name */
- if( memcmp(buf+1, "gpg", 3 ) && memcmp(buf+1, "g10", 3 ) ) {
+ if( memcmp(buf+1, "gpg", 3 ) ) {
log_error_f( db_name, _("not a trustdb file\n") );
rc = G10ERR_TRUSTDB;
}
@@ -306,51 +317,60 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
(ulong)recnum );
rc = G10ERR_TRUSTDB;
}
- if( rec->r.ver.version != 1 ) {
+ if( rec->r.ver.version != 2 ) {
log_error_f( db_name, "invalid file version %d\n",
rec->r.ver.version );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_DIR: /*directory record */
- rec->r.dir.local_id = buftoulong(p); p += 4;
- rec->r.dir.keyid[0] = buftou32(p); p += 4;
- rec->r.dir.keyid[1] = buftou32(p); p += 4;
- rec->r.dir.keyrec = buftoulong(p); p += 4;
- rec->r.dir.ctlrec = buftoulong(p); p += 4;
- rec->r.dir.sigrec = buftoulong(p); p += 4;
- rec->r.dir.no_sigs = *p++;
- if( rec->r.dir.local_id != recnum ) {
- log_error_f( db_name, "dir local_id != recnum (%lu,%lu)\n",
- (ulong)rec->r.dir.local_id,
- (ulong)recnum );
+ rec->r.dir.lid = buftoulong(p); p += 4;
+ rec->r.dir.keylist = buftoulong(p); p += 4;
+ rec->r.dir.uidlist = buftoulong(p); p += 4;
+ rec->r.dir.cacherec = buftoulong(p); p += 4;
+ rec->r.dir.ownertrust = *p++;
+ rec->r.dir.sigflag = *p++;
+ if( rec->r.dir.lid != recnum ) {
+ log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
+ rec->r.dir.lid, (ulong)recnum );
rc = G10ERR_TRUSTDB;
}
break;
case RECTYPE_KEY: /* public key record */
- rec->r.key.owner = buftoulong(p); p += 4;
- rec->r.dir.keyid[0] = buftou32(p); p += 4;
- rec->r.dir.keyid[1] = buftou32(p); p += 4;
+ rec->r.key.lid = buftoulong(p); p += 4;
+ rec->r.key.next = buftoulong(p); p += 4;
+ p += 8;
rec->r.key.pubkey_algo = *p++;
rec->r.key.fingerprint_len = *p++;
if( rec->r.key.fingerprint_len < 1 || rec->r.key.fingerprint_len > 20 )
rec->r.key.fingerprint_len = 20;
- memcpy( rec->r.key.fingerprint, p, 20); p += 20;
- rec->r.key.ownertrust = *p++;
+ memcpy( rec->r.key.fingerprint, p, 20);
break;
- case RECTYPE_CTL: /* control record */
- rec->r.ctl.owner = buftoulong(p); p += 4;
- memcpy(rec->r.ctl.blockhash, p, 20); p += 20;
- rec->r.ctl.trustlevel = *p++;
+ case RECTYPE_UID: /* user id record */
+ rec->r.uid.lid = buftoulong(p); p += 4;
+ rec->r.uid.next = buftoulong(p); p += 4;
+ rec->r.uid.prefrec = buftoulong(p); p += 4;
+ rec->r.uid.siglist = buftoulong(p); p += 4;
+ p += 2;
+ memcpy( rec->r.uid.namehash, p, 20);
+ break;
+ case RECTYPE_PREF: /* preference record */
+ rec->r.pref.lid = buftoulong(p); p += 4;
+ rec->r.pref.next = buftoulong(p); p += 4;
break;
case RECTYPE_SIG:
- rec->r.sig.owner = buftoulong(p); p += 4;
- rec->r.sig.chain = buftoulong(p); p += 4;
+ rec->r.sig.lid = buftoulong(p); p += 4;
+ rec->r.sig.next = buftoulong(p); p += 4;
for(i=0; i < SIGS_PER_RECORD; i++ ) {
- rec->r.sig.sig[i].local_id = buftoulong(p); p += 4;
+ rec->r.sig.sig[i].lid = buftoulong(p); p += 4;
rec->r.sig.sig[i].flag = *p++;
}
break;
+ case RECTYPE_CACH: /* cache record (FIXME)*/
+ rec->r.cache.lid = buftoulong(p); p += 4;
+ memcpy(rec->r.cache.blockhash, p, 20); p += 20;
+ rec->r.cache.trustlevel = *p++;
+ break;
default:
log_error_f( db_name, "invalid record type %d at recnum %lu\n",
rec->rectype, (ulong)recnum );
@@ -385,40 +405,53 @@ tdbio_write_record( ulong recnum, TRUSTREC *rec )
break;
case RECTYPE_DIR: /*directory record */
- ulongtobuf(p, rec->r.dir.local_id); p += 4;
- u32tobuf(p, rec->r.key.keyid[0]); p += 4;
- u32tobuf(p, rec->r.key.keyid[1]); p += 4;
- ulongtobuf(p, rec->r.dir.keyrec); p += 4;
- ulongtobuf(p, rec->r.dir.ctlrec); p += 4;
- ulongtobuf(p, rec->r.dir.sigrec); p += 4;
- *p++ = rec->r.dir.no_sigs;
- assert( rec->r.dir.local_id == recnum );
+ ulongtobuf(p, rec->r.dir.lid); p += 4;
+ ulongtobuf(p, rec->r.dir.keylist); p += 4;
+ ulongtobuf(p, rec->r.dir.uidlist); p += 4;
+ ulongtobuf(p, rec->r.dir.cacherec); p += 4;
+ *p++ = rec->r.dir.ownertrust;
+ *p++ = rec->r.dir.sigflag;
+ assert( rec->r.dir.lid == recnum );
break;
case RECTYPE_KEY:
- ulongtobuf(p, rec->r.key.owner); p += 4;
- u32tobuf(p, rec->r.key.keyid[0]); p += 4;
- u32tobuf(p, rec->r.key.keyid[1]); p += 4;
+ ulongtobuf(p, rec->r.key.lid); p += 4;
+ ulongtobuf(p, rec->r.key.next); p += 4;
+ p += 8;
*p++ = rec->r.key.pubkey_algo;
*p++ = rec->r.key.fingerprint_len;
memcpy( p, rec->r.key.fingerprint, 20); p += 20;
- *p++ = rec->r.key.ownertrust;
break;
- case RECTYPE_CTL: /* control record */
- ulongtobuf(p, rec->r.ctl.owner); p += 4;
- memcpy(p, rec->r.ctl.blockhash, 20); p += 20;
- *p++ = rec->r.ctl.trustlevel;
+ case RECTYPE_UID: /* user id record */
+ ulongtobuf(p, rec->r.uid.lid); p += 4;
+ ulongtobuf(p, rec->r.uid.next); p += 4;
+ ulongtobuf(p, rec->r.uid.prefrec); p += 4;
+ ulongtobuf(p, rec->r.uid.siglist); p += 4;
+ p += 2;
+ memcpy( p, rec->r.uid.namehash, 20 ); p += 20;
+ break;
+
+ case RECTYPE_PREF:
+ ulongtobuf(p, rec->r.pref.lid); p += 4;
+ ulongtobuf(p, rec->r.pref.next); p += 4;
break;
case RECTYPE_SIG:
- ulongtobuf(p, rec->r.sig.owner); p += 4;
- ulongtobuf(p, rec->r.sig.chain); p += 4;
+ ulongtobuf(p, rec->r.sig.lid); p += 4;
+ ulongtobuf(p, rec->r.sig.next); p += 4;
for(i=0; i < SIGS_PER_RECORD; i++ ) {
- ulongtobuf(p, rec->r.sig.sig[i].local_id); p += 4;
+ ulongtobuf(p, rec->r.sig.sig[i].lid); p += 4;
*p++ = rec->r.sig.sig[i].flag;
}
break;
+
+ case RECTYPE_CACH: /* FIXME*/
+ ulongtobuf(p, rec->r.cache.lid); p += 4;
+ memcpy(p, rec->r.cache.blockhash, 20); p += 20;
+ *p++ = rec->r.cache.trustlevel;
+ break;
+
default:
BUG();
}
@@ -475,7 +508,7 @@ tdbio_new_recnum()
* Note: To increase performance, we could use a index search here.
*/
int
-tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
+tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec )
{
ulong recnum;
u32 keyid[2];
@@ -484,30 +517,26 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
int rc;
keyid_from_pk( pk, keyid );
- fingerprint = fingerprint_from_pk( pk, &fingerlen );
+ fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen );
assert( fingerlen == 20 || fingerlen == 16 );
for(recnum=1; !(rc=tdbio_read_record( recnum, rec, 0)); recnum++ ) {
- if( rec->rectype != RECTYPE_DIR )
+ if( rec->rectype != RECTYPE_KEY )
continue;
- if( rec->r.dir.keyid[0] == keyid[0]
- && rec->r.dir.keyid[1] == keyid[1]){
- TRUSTREC keyrec;
-
- if( tdbio_read_record( rec->r.dir.keyrec, &keyrec, RECTYPE_KEY ) ) {
- log_error("%lu: ooops: invalid key record\n", recnum );
+ if( rec->r.key.pubkey_algo == pk->pubkey_algo
+ && !memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) {
+ /* found: read the dir record for this key */
+ rc = tdbio_read_record( rec->r.key.lid, rec, RECTYPE_DIR);
+ if( rc )
break;
- }
- if( keyrec.r.key.pubkey_algo == pk->pubkey_algo
- && !memcmp(keyrec.r.key.fingerprint, fingerprint, fingerlen) ){
- if( pk->local_id && pk->local_id != recnum )
- log_error_f(db_name,
- "found record, but local_id from memory does "
- "not match recnum (%lu,%lu)\n",
- (ulong)pk->local_id, (ulong)recnum );
- pk->local_id = recnum;
- return 0;
- }
+
+ if( pk->local_id && pk->local_id != recnum )
+ log_error_f(db_name,
+ "found record, but LID from memory does "
+ "not match recnum (%lu,%lu)\n",
+ pk->local_id, recnum );
+ pk->local_id = recnum;
+ return 0;
}
}
if( rc != -1 )
@@ -516,3 +545,22 @@ tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec )
}
+int
+tdbio_update_sigflag( ulong lid, int sigflag )
+{
+ TRUSTREC rec;
+
+ if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
+ log_error("update_sigflag: read failed\n");
+ return G10ERR_TRUSTDB;
+ }
+
+ rec.r.dir.sigflag = sigflag;
+ if( tdbio_write_record( lid, &rec ) ) {
+ log_error("update_sigflag: write failed\n");
+ return G10ERR_TRUSTDB;
+ }
+
+ return 0;
+}
+
diff --git a/g10/tdbio.h b/g10/tdbio.h
index facb5c307..7229d7222 100644
--- a/g10/tdbio.h
+++ b/g10/tdbio.h
@@ -32,15 +32,17 @@
#define RECTYPE_VER 1
#define RECTYPE_DIR 2
#define RECTYPE_KEY 3
-#define RECTYPE_CTL 4
-#define RECTYPE_SIG 5
-#define RECTYPE_HTBL 6
-#define RECTYPE_HLST 7
-#define RECTYPE_UID 8
+#define RECTYPE_UID 4
+#define RECTYPE_PREF 5
+#define RECTYPE_SIG 6
+#define RECTYPE_CACH 9
+#define RECTYPE_HTBL 10
+#define RECTYPE_HLST 11
struct trust_record {
int rectype;
+ struct trust_record *next;
union {
struct { /* version record: */
byte version; /* should be 1 */
@@ -53,49 +55,50 @@ struct trust_record {
byte max_cert_depth;
} ver;
struct { /* directory record */
- ulong local_id;
- u32 keyid[2];
- ulong keyrec; /* recno of primary public key record */
- ulong ctlrec; /* recno of control record */
- ulong sigrec; /* recno of first signature record (osolete) */
- ulong uidrec; /* recno of first user-id record */
- ulong link; /* to next dir record */
- byte no_sigs; /* does not have sigature and checked */
+ ulong lid;
+ ulong keylist; /* List of keys (the first is the primary key)*/
+ ulong uidlist; /* list of uid records */
+ ulong cacherec; /* the cache record */
+ byte ownertrust;
+ byte sigflag;
} dir;
struct { /* primary public key record */
- ulong owner;
- u32 keyid[2];
+ ulong lid;
+ ulong next; /* next key */
byte pubkey_algo;
byte fingerprint_len;
byte fingerprint[20];
- byte ownertrust;
} key;
struct { /* user id reord */
- ulong owner; /* point back to the directory record */
- ulong chain; /* points to next user id record */
- byte subtype; /* must be 0 */
- byte namehash[20]; /* ripemd hash of the username */
- byte ownertrust;
- u32 prefrec; /* recno of reference record */
+ ulong lid; /* point back to the directory record */
+ ulong next; /* points to next user id record */
+ ulong prefrec; /* recno of reference record */
+ ulong siglist; /* list of valid signatures (w/o self-sig)*/
+ byte namehash[20]; /* ripemd hash of the username */
} uid;
- struct { /* control record */
- ulong owner;
- byte blockhash[20];
- byte trustlevel; /* calculated trustlevel */
- } ctl;
+ struct { /* preference reord */
+ ulong lid; /* point back to the directory record */
+ /* or 0 for a glocal pref record */
+ ulong next; /* points to next pref record */
+ } pref;
struct { /* signature record */
- ulong owner; /* local_id of record owner (pubkey record) */
- ulong chain; /* offset of next record or NULL for last one */
+ ulong lid;
+ ulong next; /* recnno of next record or NULL for last one */
struct {
- ulong local_id; /* of pubkey record of signator (0=unused) */
- byte flag; /* reserved */
+ ulong lid; /* of pubkey record of signator (0=unused) */
+ byte flag; /* reserved */
} sig[SIGS_PER_RECORD];
} sig;
+ struct { /* cache record */
+ ulong lid;
+ byte blockhash[20];
+ byte trustlevel; /* calculated trustlevel */
+ } cache;
struct {
ulong item[ITEMS_PER_HTBL_RECORD];
} htbl;
struct {
- ulong chain;
+ ulong next;
struct {
byte hash;
ulong rnum;
@@ -126,7 +129,8 @@ void tdbio_dump_record( ulong rnum, TRUSTREC *rec, FILE *fp );
int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected );
int tdbio_write_record( ulong recnum, TRUSTREC *rec );
ulong tdbio_new_recnum(void);
-int tdbio_search_record( PKT_public_key *pk, TRUSTREC *rec );
+int tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec );
+int tdbio_update_sigflag( ulong lid, int sigflag );
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
diff --git a/g10/trustdb.c b/g10/trustdb.c
index 916eeffd1..593e12cd2 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -42,6 +42,10 @@
#include "tdbio.h"
+#if MAX_FINGERPRINT_LEN > 20
+ #error Must change structure of trustdb
+#endif
+
typedef struct local_id_info *LOCAL_ID_INFO;
struct local_id_info {
LOCAL_ID_INFO next;
@@ -85,11 +89,10 @@ static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
static int list_sigs( ulong pubkey_id );
-static int build_sigrecs( ulong pubkeyid );
+static int build_sigrecs( ulong local_id );
static int propagate_trust( TRUST_SEG_LIST tslist );
-static int do_check( ulong pubkeyid, TRUSTREC *drec, unsigned *trustlevel );
+static int do_check( TRUSTREC *drec, unsigned *trustlevel );
-static int update_no_sigs( ulong lid, int no_sigs );
/* a table used to keep track of ultimately trusted keys
* which are the ones from our secrings */
@@ -186,12 +189,11 @@ set_signature_packets_local_id( PKT_signature *sig )
if( rc)
goto leave;
if( !pk->local_id ) {
- rc = tdbio_search_record( pk, &rec );
+ rc = tdbio_search_dir_record( pk, &rec );
if( rc == -1 )
rc = insert_trust_record( pk );
if( rc )
goto leave;
- /* fixme: we should propagate the local_id to all copies of the PK */
}
sig->local_id = pk->local_id;
@@ -666,35 +668,36 @@ check_sigs( KBNODE keyblock, int *selfsig_okay, int *revoked )
* to the trustdb
*/
static int
-build_sigrecs( ulong pubkeyid )
+build_sigrecs( ulong lid )
{
TRUSTREC rec, krec, rec2;
- KBNODE keyblock = NULL;
- KBNODE node;
+ KBNODE keyblock = NULL;
+ KBNODE node;
int rc=0;
int i, selfsig, revoked;
ulong rnum, rnum2;
ulong first_sigrec = 0;
if( DBG_TRUST )
- log_debug("trustdb: build_sigrecs for pubkey %lu\n", (ulong)pubkeyid );
+ log_debug("trustdb: build_sigrecs for LID %lu\n", lid );
/* get the keyblock */
- if( (rc=tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
- log_error(_("%lu: build_sigrecs: can't read dir record\n"), pubkeyid );
+ if( (rc=tdbio_read_record( lid, &rec, RECTYPE_DIR )) ) {
+ log_error( "build_sigrecs: can't read dir record %lu\n"), lid );
goto leave;
}
- if( (rc=tdbio_read_record( rec.r.dir.keyrec, &krec, RECTYPE_KEY )) ) {
- log_error(_("%lu: build_sigrecs: can't read key record\n"), pubkeyid);
+ if( (rc=tdbio_read_record( rec.r.dir.keylist, &krec, RECTYPE_KEY )) ) {
+ log_error("build_sigrecs: can't read primary key record %lu\n"), lid);
goto leave;
}
rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint,
krec.r.key.fingerprint_len );
if( rc ) {
- log_error(_("build_sigrecs: get_keyblock_byfprint failed: %s\n"),
- g10_errstr(rc) );
+ log_error( "build_sigrecs: keyblock for %lu not found: %s\n",
+ lid, g10_errstr(rc) );
goto leave;
}
+
/* check all key signatures */
rc = check_sigs( keyblock, &selfsig, &revoked );
if( rc ) {
@@ -703,19 +706,18 @@ build_sigrecs( ulong pubkeyid )
}
if( !selfsig ) {
log_error(_("build_sigrecs: self-signature missing\n") );
- update_no_sigs( pubkeyid, 2 );
+ tdbio_update_sigflag( lid, 2 );
rc = G10ERR_BAD_CERT;
goto leave;
}
if( revoked ) {
log_info(_("build_sigrecs: key has been revoked\n") );
- update_no_sigs( pubkeyid, 3 );
+ tdbio_update_sigflag( lid, 3 );
}
else
- update_no_sigs( pubkeyid, 0 ); /* assume we have sigs */
+ tdbio_update_sigflag( lid, 0 ); /* assume we have sigs */
- /* valid key signatures are now marked; we can now build the
- * sigrecs */
+ /* valid key signatures are now marked; we can now build the sigrecs */
memset( &rec, 0, sizeof rec );
rec.rectype = RECTYPE_SIG;
i = 0;
@@ -740,8 +742,8 @@ build_sigrecs( ulong pubkeyid )
/* write the record */
rnum = tdbio_new_recnum();
if( rnum2 ) { /* write the stored record */
- rec2.r.sig.owner = pubkeyid;
- rec2.r.sig.chain = rnum; /* the next record number */
+ rec2.r.sig.lid = lid;
+ rec2.r.sig.next = rnum; /* the next record number */
rc = tdbio_write_record( rnum2, &rec2 );
if( rc ) {
log_error(_("build_sigrecs: write_record failed\n") );
@@ -756,7 +758,7 @@ build_sigrecs( ulong pubkeyid )
rec.rectype = RECTYPE_SIG;
i = 0;
}
- rec.r.sig.sig[i].local_id = node->pkt->pkt.signature->local_id;
+ rec.r.sig.sig[i].lid = node->pkt->pkt.signature->local_id;
rec.r.sig.sig[i].flag = 0;
i++;
}
@@ -765,8 +767,8 @@ build_sigrecs( ulong pubkeyid )
/* write the record */
rnum = tdbio_new_recnum();
if( rnum2 ) { /* write the stored record */
- rec2.r.sig.owner = pubkeyid;
- rec2.r.sig.chain = rnum;
+ rec2.r.sig.lid = lid;
+ rec2.r.sig.next = rnum;
rc = tdbio_write_record( rnum2, &rec2 );
if( rc ) {
log_error(_("build_sigrecs: write_record failed\n") );
@@ -776,8 +778,8 @@ build_sigrecs( ulong pubkeyid )
first_sigrec = rnum2;
}
if( i ) { /* write the pending record */
- rec.r.sig.owner = pubkeyid;
- rec.r.sig.chain = 0;
+ rec.r.sig.lid = lid;
+ rec.r.sig.next = 0;
rc = tdbio_write_record( rnum, &rec );
if( rc ) {
log_error(_("build_sigrecs: write_record failed\n") );
@@ -787,8 +789,7 @@ build_sigrecs( ulong pubkeyid )
first_sigrec = rnum;
}
}
- if( first_sigrec ) {
- /* update the dir record */
+ if( first_sigrec ) { /* update the uid records */
if( (rc =tdbio_read_record( pubkeyid, &rec, RECTYPE_DIR )) ) {
log_error(_("update_dir_record: read failed\n"));
goto leave;
@@ -800,7 +801,7 @@ build_sigrecs( ulong pubkeyid )
}
}
else
- update_no_sigs( pubkeyid, revoked? 3:1 ); /* no signatures */
+ tdbio_update_sigflag( lid, revoked? 3:1 ); /* no signatures */
leave:
release_kbnode( keyblock );
@@ -900,12 +901,24 @@ propagate_trust( TRUST_SEG_LIST tslist )
}
+
/****************
- * we have the pubkey record but nothing more is known.
- * (function may re-read dr)
+ * check whether we already build signature records
+ * Return: true if we have.
*/
static int
-do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
+do_we_have_sigs( TRUSTREC *dr )
+{
+}
+
+
+/****************
+ * we have the pubkey record and all needed informations are in the trustdb
+ * but nothing more is known.
+ * (this function may re-read the dir record dr)
+ */
+static int
+do_check( TRUSTREC *dr, unsigned *trustlevel )
{
int i, rc=0;
TRUST_SEG_LIST tsl, tsl2, tslist;
@@ -919,16 +932,27 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
*trustlevel = TRUST_UNDEFINED;
+ if( !dr->r.dir.keylist ) {
+ log_error("Ooops, no keys\n");
+ return G10ERR_TRUSTDB
+ }
+ if( !dr->r.dir.uidlist ) {
+ log_error("Ooops, no user ids\n");
+ return G10ERR_TRUSTDB
+ }
+
/* verify the cache */
/* do we have sigrecs */
- if( !dr->r.dir.sigrec && !dr->r.dir.no_sigs) {
- /* no sigrecs, so build them */
- rc = build_sigrecs( pubkeyid );
+ if( !do_we_have_sigs( dr ) ) { /* no sigrecs, so build them */
+ rc = build_sigrecs( dr->lid );
if( !rc ) /* and read again */
- rc = tdbio_read_record( pubkeyid, dr, RECTYPE_DIR );
+ rc = tdbio_read_record( dr->lid, dr, RECTYPE_DIR );
}
+
+ !!!!WORK!!!!
+
if( dr->r.dir.no_sigs == 3 )
tflags |= TRUST_FLAG_REVOKED;
@@ -1199,9 +1223,7 @@ list_trust_path( int max_depth, const char *username )
* yes: return trustlevel from cache
* no: make a cache record and all the other stuff
* not found:
- * Return with a trustlevel, saying that we do not have
- * a trust record for it. The caller may use insert_trust_record()
- * and then call this function here again.
+ * try to insert the pubkey into the trustdb and check again
*
* Problems: How do we get the complete keyblock to check that the
* cache record is actually valid? Think we need a clever
@@ -1225,17 +1247,17 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
/* get the pubkey record */
if( pk->local_id ) {
if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
- log_error(_("check_trust: read dir record failed\n"));
+ log_error("check_trust: read dir record failed\n");
return G10ERR_TRUSTDB;
}
}
else { /* no local_id: scan the trustdb */
- if( (rc=tdbio_search_record( pk, &rec )) && rc != -1 ) {
- log_error(_("check_trust: search_record failed: %s\n"),
+ if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) {
+ log_error("check_trust: search dir record failed: %s\n",
g10_errstr(rc));
return rc;
}
- else if( rc == -1 ) {
+ else if( rc == -1 ) { /* not found - insert */
rc = insert_trust_record( pk );
if( rc ) {
log_error(_("key %08lX: insert trust record failed: %s\n"),
@@ -1263,7 +1285,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
trustlevel = TRUST_EXPIRED;
}
else {
- rc = do_check( pk->local_id, &rec, &trustlevel );
+ rc = do_check( &rec, &trustlevel );
if( rc ) {
log_error(_("key %08lX.%lu: trust check failed: %s\n"),
keyid[1], pk->local_id, g10_errstr(rc));
@@ -1424,24 +1446,119 @@ query_trust_record( PKT_public_key *pk )
* This function fails if this record already exists.
*/
int
-insert_trust_record( PKT_public_key *pk )
+insert_trust_record( PKT_public_key *orig_pk )
{
- TRUSTREC rec;
+ TRUSTREC dirrec, *rec;
+ TRUSTREC **keylist_tail, *keylist;
+ TRUSTREC **uidlist_tail, *uidlist;
+ KBNODE keyblock = NULL;
+ KBNODE node;
u32 keyid[2];
ulong knum, dnum;
byte *fingerprint;
size_t fingerlen;
+ int rc = 0;
- if( pk->local_id )
+ if( orig_pk->local_id )
log_bug("pk->local_id=%lu\n", (ulong)pk->local_id );
- keyid_from_pk( pk, keyid );
- fingerprint = fingerprint_from_pk( pk, &fingerlen );
+ fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+
+ /* fixme: assert that we do not have this record.
+ * we can do this by searching for the primary keyid
+ */
+
+ /* get the keyblock which has the key */
+ rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
+ if( rc ) { /* that should never happen */
+ log_error( "insert_trust_record: keyblock not found: %s\n",
+ g10_errstr(rc) );
+ return rc;
+ }
+
+ /* prepare dir record */
+ memset( &dirrec, 0, sizeof dirrec );
+ dirrec.rectype = RECTYPE_DIR;
+ dirrec.r.dir.lid = tdbio_new_recnum();
+
+ keylist = NULL;
+ keylist_tail = &dirrec.r.dir.keylist;
+ uidlist = NULL;
+ uidlist_tail = &dirrec.r.dir.uidlist;
+ /* loop over the keyblock */
+ for( node=keyblock; node; node = node->next ) {
+ if( node->pkt->pkttype == PKT_PUBLIC_KEY
+ || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+ PKT_public_key *pk = node->pkt->pkt.public_key;
+
+ if( keylist && node->pkt->pkttype == PKT_PUBLIC_KEY )
+ BUG(); /* more than one primary key */
+ fingerprint = fingerprint_from_pk( orig_pk, &fingerlen );
+ rec = m_alloc_clear( sizeof *rec );
+ rec->r.key.pubkey_algo = pk->pubkey_algo;
+ rec->r.key.fingerprint_len = fingerlen;
+ memcpy(rec->r.key.fingerprint, fingerprint, fingerlen );
+
+ if( keylist )
+ keylist_tail = &keylist->next;
+ *keylist_tail = keylist = rec;
+ }
+ else if( node->pkt->pkttype == PKT_USER_ID ) {
+ PKT_user_id *uid = node->pkt->pkt.user_id;
+
+ rec = m_alloc_clear( sizeof *rec );
+ rmd160_hash_buffer( rec->r.uid.namehash, uid->name, uid->len );
+
+ if( uidlist )
+ uidlist_tail = &uidlist->next;
+ *uidlist_tail = uidlist = rec;
+ }
+ if( node->pkt->pkttype == PKT_SIGNATURE
+ && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
+ || node->pkt->pkt.signature->sig_class == 0x20
+ || node->pkt->pkt.signature->sig_class == 0x30) ) {
+ int selfsig;
+ rc = check_key_signature( keyblock, node, &selfsig );
+ if( !rc ) {
+ rc = set_signature_packets_local_id( node->pkt->pkt.signature );
+ if( rc )
+ log_fatal("set_signature_packets_local_id failed: %s\n",
+ g10_errstr(rc));
+ if( selfsig ) {
+ node->flag |= 2; /* mark signature valid */
+ *selfsig_okay = 1;
+ }
+ else if( node->pkt->pkt.signature->sig_class == 0x20 )
+ *revoked = 1;
+ else
+ node->flag |= 1; /* mark signature valid */
+
+ if( node->pkt->pkt.signature->sig_class != 0x20 ) {
+ if( !dups )
+ dups = new_lid_table();
+ if( ins_lid_table_item( dups,
+ node->pkt->pkt.signature->local_id, 0) )
+ node->flag |= 4; /* mark as duplicate */
+ }
+ }
+ if( DBG_TRUST )
+ log_debug("trustdb: sig from %08lX.%lu: %s%s\n",
+ (ulong)node->pkt->pkt.signature->keyid[1],
+ node->pkt->pkt.signature->local_id,
+ g10_errstr(rc), (node->flag&4)?" (dup)":"" );
+ }
+ }
+
+
+
+
+
+
+
+
- /* fixme: assert that we do not have this record. */
- dnum = tdbio_new_recnum();
knum = tdbio_new_recnum();
/* build dir record */
memset( &rec, 0, sizeof rec );
@@ -1451,10 +1568,6 @@ insert_trust_record( PKT_public_key *pk )
rec.r.dir.keyid[1] = keyid[1];
rec.r.dir.keyrec = knum;
rec.r.dir.no_sigs = 0;
- if( tdbio_write_record( dnum, &rec ) ) {
- log_error("writing dir record failed\n");
- return G10ERR_TRUSTDB;
- }
/* and the key record */
memset( &rec, 0, sizeof rec );
rec.rectype = RECTYPE_KEY;
@@ -1469,8 +1582,14 @@ insert_trust_record( PKT_public_key *pk )
log_error("wrinting key record failed\n");
return G10ERR_TRUSTDB;
}
+
+ if( tdbio_write_record( dirrec.r.dir.lid, &dirrec ) ) {
+ log_error("writing dir record failed\n");
+ return G10ERR_TRUSTDB;
+ }
+
/* and store the LID */
- pk->local_id = dnum;
+ orig_pk->local_id = dnum;
return 0;
}
@@ -1504,27 +1623,5 @@ update_ownertrust( ulong lid, unsigned new_trust )
-/****************
- * Kludge to prevent duplicate build_sigrecs() due to an invalid
- * certificate (no selfsignature or something like this)
- */
-static int
-update_no_sigs( ulong lid, int no_sigs )
-{
- TRUSTREC rec;
-
- if( tdbio_read_record( lid, &rec, RECTYPE_DIR ) ) {
- log_error("update_no_sigs: read failed\n");
- return G10ERR_TRUSTDB;
- }
-
- rec.r.dir.no_sigs = no_sigs;
- if( tdbio_write_record( lid, &rec ) ) {
- log_error("update_no_sigs: write failed\n");
- return G10ERR_TRUSTDB;
- }
-
- return 0;
-}
diff --git a/g10/verify.c b/g10/verify.c
index 7a2f73130..02cc5d003 100644
--- a/g10/verify.c
+++ b/g10/verify.c
@@ -77,7 +77,7 @@ verify_signatures( int nfiles, char **files )
sl = NULL;
for(i=1 ; i < nfiles; i++ )
add_to_strlist( &sl, files[i] );
- rc = proc_signature_packets( fp, sl );
+ rc = proc_signature_packets( fp, sl, sigfile );
free_strlist(sl);
iobuf_close(fp);
return rc;