added revcation stuff and fixed a couple of bugs

This commit is contained in:
Werner Koch 1998-02-18 13:58:46 +00:00
parent c8bb57d05d
commit b758180325
24 changed files with 441 additions and 117 deletions

14
NEWS
View File

@ -1,11 +1,21 @@
Noteworthy changes in version 0.2.7 Noteworthy changes in version 0.2.7
----------------------------------- -----------------------------------
* new option --dearmot for g10maint * New command "gen-revoke" to create a key revocation certificate.
* option --version now conforming to the GNU standards and lists * New option "homedir" to set the homedir (which defaults to "~/.g10").
This directory is created if it does not exists (only the last
part of the name and not the complete hierarchy)
* Command "import" works. (Try: "finger gcrypt@ftp.guug.de|g10 --import")
* New commands "dearmor/enarmor" for g10maint. These are mainly
used for internal test purposes.
* Option --version now conforming to the GNU standards and lists
the available ciphers, message digests and public key algorithms. the available ciphers, message digests and public key algorithms.
* Assembler code for m68k (not tested).
Noteworthy changes in version 0.2.6 Noteworthy changes in version 0.2.6
----------------------------------- -----------------------------------

View File

@ -1,3 +1,7 @@
Wed Feb 18 14:08:30 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c, md.h : New debugging support
Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de) Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
* misc.c (cipher_algo_to_string): New * misc.c (cipher_algo_to_string): New

View File

@ -27,10 +27,6 @@
#include "cipher.h" #include "cipher.h"
#include "errors.h" #include "errors.h"
/*static FILE *dumpfp;*/
/**************** /****************
* Open a message digest handle for use with algorithm ALGO. * Open a message digest handle for use with algorithm ALGO.
* More algorithms may be added by md_enable(). The initial algorithm * More algorithms may be added by md_enable(). The initial algorithm
@ -41,13 +37,6 @@ md_open( int algo, int secure )
{ {
MD_HANDLE hd; MD_HANDLE hd;
#if 0
if( !dumpfp )
dumpfp = fopen("md.out", "w");
if( !dumpfp )
BUG();
{ int i; for(i=0; i < 16; i++ ) putc('\xff', dumpfp ); }
#endif
hd = secure ? m_alloc_secure_clear( sizeof *hd ) hd = secure ? m_alloc_secure_clear( sizeof *hd )
: m_alloc_clear( sizeof *hd ); : m_alloc_clear( sizeof *hd );
hd->secure = secure; hd->secure = secure;
@ -81,7 +70,6 @@ md_copy( MD_HANDLE a )
{ {
MD_HANDLE b; MD_HANDLE b;
/*{ int i; for(i=0; i < 16; i++ ) putc('\xee', dumpfp ); }*/
b = a->secure ? m_alloc_secure( sizeof *b ) b = a->secure ? m_alloc_secure( sizeof *b )
: m_alloc( sizeof *b ); : m_alloc( sizeof *b );
memcpy( b, a, sizeof *a ); memcpy( b, a, sizeof *a );
@ -101,10 +89,12 @@ md_close(MD_HANDLE a)
void void
md_write( MD_HANDLE a, byte *inbuf, size_t inlen) md_write( MD_HANDLE a, byte *inbuf, size_t inlen)
{ {
/* if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, dumpfp ) != 1 ) if( a->debug ) {
BUG(); if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, a->debug ) != 1 )
if( inlen && fwrite(inbuf, inlen, 1, dumpfp ) != 1 ) BUG();
BUG(); */ if( inlen && fwrite(inbuf, inlen, 1, a->debug ) != 1 )
BUG();
}
if( a->use_rmd160 ) { if( a->use_rmd160 ) {
rmd160_write( &a->rmd160, a->buffer, a->bufcount ); rmd160_write( &a->rmd160, a->buffer, a->bufcount );
rmd160_write( &a->rmd160, inbuf, inlen ); rmd160_write( &a->rmd160, inbuf, inlen );
@ -127,7 +117,6 @@ md_final(MD_HANDLE a)
{ {
if( a->bufcount ) if( a->bufcount )
md_write( a, NULL, 0 ); md_write( a, NULL, 0 );
/*{ int i; for(i=0; i < 16; i++ ) putc('\xcc', dumpfp ); }*/
if( a->use_rmd160 ) { if( a->use_rmd160 ) {
byte *p; byte *p;
rmd160_final( &a->rmd160 ); rmd160_final( &a->rmd160 );

View File

@ -20,6 +20,7 @@
#ifndef G10_MD_H #ifndef G10_MD_H
#define G10_MD_H #define G10_MD_H
#include <stdio.h>
#include "types.h" #include "types.h"
#include "rmd.h" #include "rmd.h"
#include "sha1.h" #include "sha1.h"
@ -37,6 +38,7 @@ typedef struct {
byte buffer[MD_BUFFER_SIZE]; /* primary buffer */ byte buffer[MD_BUFFER_SIZE]; /* primary buffer */
int bufcount; int bufcount;
int secure; int secure;
FILE *debug;
} *MD_HANDLE; } *MD_HANDLE;

View File

@ -6,6 +6,10 @@
a rmd160 hash value from it. This is used as the a rmd160 hash value from it. This is used as the
fingerprint and the low 64 bits are the keyid. fingerprint and the low 64 bits are the keyid.
* Revocation certificates consists only of the signature packet;
"import" knows how to handle this. The rationale behind it is
to keep them small.
@ -162,7 +166,7 @@ Record Type 6 (hash table)
if this is not the correct dir record, we look at the next if this is not the correct dir record, we look at the next
dir record which is linked by the link field. dir record which is linked by the link field.
Record type 7 (hast list) Record type 7 (hash list)
------------- -------------
see hash table for an explanation. see hash table for an explanation.
@ -175,3 +179,58 @@ Record type 7 (hast list)
For the current record length of 40, n is 6 For the current record length of 40, n is 6
Packet Headers
===============
G10 uses PGP 2 packet headers and also understand OpenPGP packet header.
There is one enhavement used ith the old style packet headers:
CTB bits 10, the "packet-length length bits", have values listed in
the following table:
00 - 1-byte packet-length field
01 - 2-byte packet-length field
10 - 4-byte packet-length field
11 - no packet length supplied, unknown packet length
As indicated in this table, depending on the packet-length length
bits, the remaining 1, 2, 4, or 0 bytes of the packet structure field
are a "packet-length field". The packet-length field is a whole
number field. The value of the packet-length field is defined to be
the value of the whole number field.
A value of 11 is currently used in one place: on compressed data.
That is, a compressed data block currently looks like <A3 01 . . .>,
where <A3>, binary 10 1000 11, is an indefinite-length packet. The
proper interpretation is "until the end of the enclosing structure",
although it should never appear outermost (where the enclosing
structure is a file).
+ This will be changed with another version, where the new meaning of
+ the value 11 (see below) will also take place.
+
+ A value of 11 for other packets enables a special length encoding,
+ which is used in case, where the length of the following packet can
+ not be determined prior to writing the packet; especially this will
+ be used if large amounts of data are processed in filter mode.
+
+ It works like this: After the CTB (with a length field of 11) a
+ marker field is used, which gives the length of the following datablock.
+ This is a simple 2 byte field (MSB first) containig the amount of data
+ following this field, not including this length field. After this datablock
+ another length field follows, which gives the size of the next datablock.
+ A value of 0 indicates the end of the packet. The maximum size of a
+ data block is limited to 65534, thereby reserving a value of 0xffff for
+ future extensions. These length markers must be insereted into the data
+ stream just before writing the data out.
+
+ This 2 byte filed is large enough, because the application must buffer
+ this amount of data to prepend the length marker before writing it out.
+ Data block sizes larger than about 32k doesn't make any sense. Note
+ that this may also be used for compressed data streams, but we must use
+ another packet version to tell the application that it can not assume,
+ that this is the last packet.

View File

@ -1,3 +1,27 @@
Wed Feb 18 13:35:58 1998 Werner Koch (wk@isil.d.shuttle.de)
* mainproc.c (do_check_sig): Now uses hash_public_cert.
* parse-packet.c (parse_certificate): Removed hashing.
* packet.h (public_cert): Removed hash variable.
* free-packet.c (copy_public_cert, free_public_cert): Likewise.
* sig-check.c (check_key_signatures): Changed semantics.
Wed Feb 18 12:11:28 1998 Werner Koch (wk@isil.d.shuttle.de)
* trustdb.c (do_check): Add handling for revocation certificates.
(build_sigrecs): Ditto.
(check_sigs): Ditto.
Wed Feb 18 09:31:04 1998 Werner Koch (wk@isil.d.shuttle.de)
* armor.c (armor_filter): Add afx->hdrlines.
* revoke.c (gen_revoke): Add comment line.
* dearmor.c (enarmor_file): Ditto.
* sig-check.c (check_key_signature): Add handling for class 0x20.
* mainproc.c : Ditto.
Tue Feb 17 21:24:17 1998 Werner Koch (wk@isil.d.shuttle.de) Tue Feb 17 21:24:17 1998 Werner Koch (wk@isil.d.shuttle.de)
* armor.c : Add header lines "...ARMORED FILE .." * armor.c : Add header lines "...ARMORED FILE .."

View File

@ -87,7 +87,7 @@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
EXTRA_DIST = OPTIONS pubring.g10 EXTRA_DIST = OPTIONS pubring.asc
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
bin_PROGRAMS = g10 g10maint bin_PROGRAMS = g10 g10maint

View File

@ -944,7 +944,10 @@ armor_filter( void *opaque, int control,
iobuf_writestr(a, "-----\n"); iobuf_writestr(a, "-----\n");
iobuf_writestr(a, "Version: G10 v" VERSION " (" iobuf_writestr(a, "Version: G10 v" VERSION " ("
PRINTABLE_OS_NAME ")\n"); PRINTABLE_OS_NAME ")\n");
iobuf_writestr(a, "Comment: This is an alpha version!\n\n"); iobuf_writestr(a, "Comment: This is an alpha version!\n");
if( afx->hdrlines )
iobuf_writestr(a, afx->hdrlines);
iobuf_put(a, '\n');
afx->status++; afx->status++;
afx->idx = 0; afx->idx = 0;
afx->idx2 = 0; afx->idx2 = 0;

View File

@ -211,7 +211,12 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
int rc = 0; int rc = 0;
int c; int c;
IOBUF a = iobuf_temp(); IOBUF a = iobuf_temp();
/* FILE *fp = fopen("dump.pkc", "a");*/ #if 1
FILE *fp = fopen("dump.pkc", "a");
int i=0;
fprintf(fp, "\nHashing PKC:\n");
#endif
/* build the packet */ /* build the packet */
init_packet(&pkt); init_packet(&pkt);
@ -220,10 +225,19 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
if( (rc = build_packet( a, &pkt )) ) if( (rc = build_packet( a, &pkt )) )
log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc)); log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
while( (c=iobuf_get(a)) != -1 ) { while( (c=iobuf_get(a)) != -1 ) {
/* putc( c, fp);*/ #if 1
fprintf( fp," %02x", c );
if( (++i == 24) ) {
putc('\n', fp);
i=0;
}
#endif
md_putc( md, c ); md_putc( md, c );
} }
/*fclose(fp);*/ #if 1
putc('\n', fp);
fclose(fp);
#endif
iobuf_cancel(a); iobuf_cancel(a);
} }

View File

@ -20,6 +20,7 @@
#ifndef G10_FILTER_H #ifndef G10_FILTER_H
#define G10_FILTER_H #define G10_FILTER_H
#include "types.h"
#include "cipher.h" #include "cipher.h"
typedef struct { typedef struct {
@ -41,6 +42,7 @@ typedef struct {
int inp_checked; /* set if inp has been checked */ int inp_checked; /* set if inp has been checked */
int inp_bypass; /* set if the input is not armored */ int inp_bypass; /* set if the input is not armored */
int inp_eof; int inp_eof;
const char *hdrlines;
} armor_filter_context_t; } armor_filter_context_t;

View File

@ -87,7 +87,6 @@ release_public_cert_parts( PKT_public_cert *cert )
mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL; 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; mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL;
} }
md_close( cert->mfx.md ); cert->mfx.md = NULL;
} }
void void
@ -112,7 +111,6 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n ); d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e ); d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
} }
d->mfx.md = NULL;
return d; return d;
} }

View File

@ -474,7 +474,7 @@ main( int argc, char **argv )
if( greeting ) { if( greeting ) {
tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) ); tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
tty_printf("%s", strusage(15) ); tty_printf("%s\n", strusage(15) );
} }
/* initialize the secure memory. */ /* initialize the secure memory. */

View File

@ -38,6 +38,7 @@
static int read_block( IOBUF a, compress_filter_context_t *cfx, static int read_block( IOBUF a, compress_filter_context_t *cfx,
PACKET **pending_pkt, KBNODE *ret_root ); PACKET **pending_pkt, KBNODE *ret_root );
static int import_one( const char *fname, KBNODE keyblock ); static int import_one( const char *fname, KBNODE keyblock );
static int import_revoke_cert( const char *fname, KBNODE node );
static int chk_self_sigs( const char *fname, KBNODE keyblock, static int chk_self_sigs( const char *fname, KBNODE keyblock,
PKT_public_cert *pkc, u32 *keyid ); PKT_public_cert *pkc, u32 *keyid );
static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ); static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid );
@ -56,7 +57,6 @@ static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
* Other signatures are not not checked. * Other signatures are not not checked.
* *
* Actually this functtion does a merge. It works like this: * Actually this functtion does a merge. It works like this:
* FIXME: add handling for revocation certs
* *
* - get the keyblock * - get the keyblock
* - check self-signatures and remove all userids and their signatures * - check self-signatures and remove all userids and their signatures
@ -78,6 +78,8 @@ static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
* is used. * is used.
* - Proceed with next signature. * - Proceed with next signature.
* *
* Key revocation certificates have a special handling.
*
*/ */
int int
import_pubkeys( const char *fname ) import_pubkeys( const char *fname )
@ -107,6 +109,9 @@ import_pubkeys( const char *fname )
while( !(rc = read_block( inp, &cfx, &pending_pkt, &keyblock) )) { while( !(rc = read_block( inp, &cfx, &pending_pkt, &keyblock) )) {
if( keyblock->pkt->pkttype == PKT_PUBLIC_CERT ) if( keyblock->pkt->pkttype == PKT_PUBLIC_CERT )
rc = import_one( fname, keyblock ); rc = import_one( fname, keyblock );
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
&& keyblock->pkt->pkt.signature->sig_class == 0x20 )
rc = import_revoke_cert( fname, keyblock );
else else
log_info("%s: skipping block of type %d\n", log_info("%s: skipping block of type %d\n",
fname, keyblock->pkt->pkttype ); fname, keyblock->pkt->pkttype );
@ -159,6 +164,16 @@ read_block( IOBUF a, compress_filter_context_t *cfx,
init_packet(pkt); init_packet(pkt);
continue; continue;
} }
if( !root && pkt->pkttype == PKT_SIGNATURE
&& pkt->pkt.signature->sig_class == 0x20 ) {
/* this is a revocation certificate which is handled
* in a special way */
root = new_kbnode( pkt );
pkt = NULL;
goto ready;
}
/* make a linked list of all packets */ /* make a linked list of all packets */
switch( pkt->pkttype ) { switch( pkt->pkttype ) {
case PKT_COMPRESSED: case PKT_COMPRESSED:
@ -332,7 +347,7 @@ import_one( const char *fname, KBNODE keyblock )
if( (rc=lock_keyblock( &kbpos )) ) if( (rc=lock_keyblock( &kbpos )) )
log_error("can't lock public keyring '%s': %s\n", log_error("can't lock public keyring '%s': %s\n",
keyblock_resource_name(&kbpos), g10_errstr(rc) ); keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=insert_keyblock( &kbpos, keyblock )) ) else if( (rc=update_keyblock( &kbpos, keyblock )) )
log_error("%s: can't write to '%s': %s\n", fname, log_error("%s: can't write to '%s': %s\n", fname,
keyblock_resource_name(&kbpos), g10_errstr(rc) ); keyblock_resource_name(&kbpos), g10_errstr(rc) );
unlock_keyblock( &kbpos ); unlock_keyblock( &kbpos );
@ -361,6 +376,105 @@ import_one( const char *fname, KBNODE keyblock )
} }
/****************
* Import a revocation certificate, this is a single signature packet.
*/
static int
import_revoke_cert( const char *fname, KBNODE node )
{
PKT_public_cert *pkc=NULL;
KBNODE onode, keyblock = NULL;
KBPOS kbpos;
u32 keyid[2];
int rc = 0;
assert( !node->next );
assert( node->pkt->pkttype == PKT_SIGNATURE );
assert( node->pkt->pkt.signature->sig_class == 0x20 );
keyid[0] = node->pkt->pkt.signature->keyid[0];
keyid[1] = node->pkt->pkt.signature->keyid[1];
pkc = m_alloc_clear( sizeof *pkc );
rc = get_pubkey( pkc, keyid );
if( rc == G10ERR_NO_PUBKEY ) {
log_info("%s: key %08lX, no public key - "
"can't apply revocation certificate\n",
fname, (ulong)keyid[1]);
rc = 0;
goto leave;
}
else if( rc ) {
log_error("%s: key %08lX, public key not found: %s\n",
fname, (ulong)keyid[1], g10_errstr(rc));
goto leave;
}
/* read the original keyblock */
rc = find_keyblock_bypkc( &kbpos, pkc );
if( rc ) {
log_error("%s: key %08lX, can't locate original keyblock: %s\n",
fname, (ulong)keyid[1], g10_errstr(rc));
goto leave;
}
rc = read_keyblock( &kbpos, &keyblock );
if( rc ) {
log_error("%s: key %08lX, can't read original keyblock: %s\n",
fname, (ulong)keyid[1], g10_errstr(rc));
goto leave;
}
/* it is okay, that node is not in keyblock because
* check_key_signature works fine for sig_class 0x20 in this
* special case. */
rc = check_key_signature( keyblock, node, NULL);
if( rc ) {
log_error("%s: key %08lX, invalid revocation certificate"
": %s - rejected\n",
fname, (ulong)keyid[1], g10_errstr(rc));
}
/* check wether we already have this */
for(onode=keyblock->next; onode; onode=onode->next ) {
if( onode->pkt->pkttype == PKT_USER_ID )
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
&& onode->pkt->pkt.signature->sig_class == 0x20
&& keyid[0] == onode->pkt->pkt.signature->keyid[0]
&& keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
rc = 0;
goto leave; /* yes, we already know about it */
}
}
/* insert it */
insert_kbnode( keyblock, clone_kbnode(node), 0 );
/* and write the keyblock back */
if( opt.verbose > 1 )
log_info("%s: writing to '%s'\n",
fname, keyblock_resource_name(&kbpos) );
if( (rc=lock_keyblock( &kbpos )) )
log_error("can't lock public keyring '%s': %s\n",
keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=update_keyblock( &kbpos, keyblock )) )
log_error("%s: can't write to '%s': %s\n", fname,
keyblock_resource_name(&kbpos), g10_errstr(rc) );
unlock_keyblock( &kbpos );
/* we are ready */
log_info("%s: key %08lX, added revocation certificate\n",
fname, (ulong)keyid[1]);
leave:
release_kbnode( keyblock );
free_public_cert( pkc );
return rc;
}
/**************** /****************
* loop over the keyblock an check all self signatures. * loop over the keyblock an check all self signatures.
* Mark all user-ids with a self-signature by setting flag bit 0. * Mark all user-ids with a self-signature by setting flag bit 0.
@ -408,10 +522,11 @@ static int
delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
{ {
KBNODE node; KBNODE node;
int nvalid=0; int nvalid=0, uid_seen=0;
for(node=keyblock->next; node; node = node->next ) { for(node=keyblock->next; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID ) { if( node->pkt->pkttype == PKT_USER_ID ) {
uid_seen = 1;
if( (node->flag & 2) || !(node->flag & 1) ) { if( (node->flag & 2) || !(node->flag & 1) ) {
if( opt.verbose ) { if( opt.verbose ) {
log_info("%s: key %08lX, removed userid '", log_info("%s: key %08lX, removed userid '",
@ -434,6 +549,23 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
&& check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo) && check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo)
&& node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA )
delete_kbnode( node ); /* build_packet() can't handle this */ delete_kbnode( node ); /* build_packet() can't handle this */
else if( node->pkt->pkttype == PKT_SIGNATURE
&& node->pkt->pkt.signature->sig_class == 0x20 ) {
if( uid_seen ) {
log_error("%s: key %08lX, revocation certificate at wrong "
"place - removed\n", fname, (ulong)keyid[1]);
delete_kbnode( node );
}
else {
int rc = check_key_signature( keyblock, node, NULL);
if( rc ) {
log_error("%s: key %08lX, invalid revocation certificate"
": %s - removed\n",
fname, (ulong)keyid[1], g10_errstr(rc));
delete_kbnode( node );
}
}
}
} }
/* note: because keyblock is the public key, it is never marked /* note: because keyblock is the public key, it is never marked
@ -460,36 +592,67 @@ static int
merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
u32 *keyid, int *n_uids, int *n_sigs ) u32 *keyid, int *n_uids, int *n_sigs )
{ {
KBNODE node_orig, node; KBNODE onode, node;
int rc; int rc, found;
/* first, try to merge new ones in */ /* 1st: handle revocation certificates */
for(node_orig=keyblock_orig->next; node_orig; node_orig=node_orig->next ) { for(node=keyblock->next; node; node=node->next ) {
if( !(node_orig->flag & 1) && node_orig->pkt->pkttype == PKT_USER_ID) { if( node->pkt->pkttype == PKT_USER_ID )
break;
else if( node->pkt->pkttype == PKT_SIGNATURE
&& node->pkt->pkt.signature->sig_class == 0x20 ) {
/* check wether we already have this */
found = 0;
for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( onode->pkt->pkttype == PKT_USER_ID )
break;
else if( onode->pkt->pkttype == PKT_SIGNATURE
&& onode->pkt->pkt.signature->sig_class == 0x20
&& node->pkt->pkt.signature->keyid[0]
== onode->pkt->pkt.signature->keyid[0]
&& node->pkt->pkt.signature->keyid[1]
== onode->pkt->pkt.signature->keyid[1] ) {
found = 1;
break;
}
}
if( !found ) {
KBNODE n2 = clone_kbnode(node);
insert_kbnode( keyblock_orig, n2, 0 );
n2->flag |= 1;
node->flag |= 1;
log_info("%s: key %08lX, added revocation certificate\n",
fname, (ulong)keyid[1]);
}
}
}
/* 2nd: try to merge new ones in */
for(onode=keyblock_orig->next; onode; onode=onode->next ) {
if( !(onode->flag & 1) && onode->pkt->pkttype == PKT_USER_ID) {
/* find the user id in the imported keyblock */ /* find the user id in the imported keyblock */
for(node=keyblock->next; node; node=node->next ) for(node=keyblock->next; node; node=node->next )
if( !(node->flag & 1) if( !(node->flag & 1)
&& node->pkt->pkttype == PKT_USER_ID && node->pkt->pkttype == PKT_USER_ID
&& !cmp_user_ids( node_orig->pkt->pkt.user_id, && !cmp_user_ids( onode->pkt->pkt.user_id,
node->pkt->pkt.user_id ) ) node->pkt->pkt.user_id ) )
break; break;
if( node ) { /* found: merge */ if( node ) { /* found: merge */
rc = merge_sigs( node_orig, node, n_sigs, fname, keyid ); rc = merge_sigs( onode, node, n_sigs, fname, keyid );
if( rc ) if( rc )
return rc; return rc;
} }
} }
} }
/* second, add new user-ids */ /* 3rd: add new user-ids */
for(node=keyblock->next; node; node=node->next ) { for(node=keyblock->next; node; node=node->next ) {
if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) { if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) {
/* do we have this in the original keyblock */ /* do we have this in the original keyblock */
for(node_orig=keyblock_orig->next; node_orig; for(onode=keyblock_orig->next; onode; onode=onode->next )
node_orig=node_orig->next ) if( !(onode->flag & 1)
if( !(node_orig->flag & 1) && onode->pkt->pkttype == PKT_USER_ID
&& node_orig->pkt->pkttype == PKT_USER_ID && cmp_user_ids( onode->pkt->pkt.user_id,
&& cmp_user_ids( node_orig->pkt->pkt.user_id,
node->pkt->pkt.user_id ) ) node->pkt->pkt.user_id ) )
break; break;
if( !node ) { /* this is a new user id: append */ if( !node ) { /* this is a new user id: append */

View File

@ -154,7 +154,6 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
skc->timestamp = pkc->timestamp = make_timestamp(); skc->timestamp = pkc->timestamp = make_timestamp();
skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/ skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL; skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
memset(&pkc->mfx, 0, sizeof pkc->mfx);
pkc->d.elg.p = pk.p; pkc->d.elg.p = pk.p;
pkc->d.elg.g = pk.g; pkc->d.elg.g = pk.g;
pkc->d.elg.y = pk.y; pkc->d.elg.y = pk.y;

View File

@ -265,11 +265,8 @@ do_check_sig( CTX c, KBNODE node )
assert( node->pkt->pkttype == PKT_SIGNATURE ); assert( node->pkt->pkttype == PKT_SIGNATURE );
sig = node->pkt->pkt.signature; sig = node->pkt->pkt.signature;
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) algo = digest_algo_from_sig( sig );
algo = sig->d.elg.digest_algo; if( !algo )
else if(sig->pubkey_algo == PUBKEY_ALGO_RSA )
algo = sig->d.rsa.digest_algo;
else
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( (rc=check_digest_algo(algo)) ) if( (rc=check_digest_algo(algo)) )
return rc; return rc;
@ -282,24 +279,36 @@ do_check_sig( CTX c, KBNODE node )
* in canonical mode ??? (calculating both modes???) */ * in canonical mode ??? (calculating both modes???) */
md = md_copy( c->mfx.md ); md = md_copy( c->mfx.md );
} }
else if( (sig->sig_class&~3) == 0x10 ) { /* classes 0x10 .. 0x13 */ else if( (sig->sig_class&~3) == 0x10
|| sig->sig_class == 0x20
|| sig->sig_class == 0x30 ) { /* classes 0x10..0x13,0x20,0x30 */
if( c->list->pkt->pkttype == PKT_PUBLIC_CERT ) { if( c->list->pkt->pkttype == PKT_PUBLIC_CERT ) {
KBNODE n1 = find_prev_kbnode( c->list, node, PKT_USER_ID ); #if 0
KBNODE n1;
if( n1 ) { if( sig->sig_class == 0x20 ) {
if( c->list->pkt->pkt.public_cert->mfx.md ) md = md_open( algo, 0 );
md = md_copy( c->list->pkt->pkt.public_cert->mfx.md ); hash_public_cert( md, c->list->pkt->pkt.public_cert );
else }
BUG(); else if( (n1=find_prev_kbnode( c->list, node, PKT_USER_ID )) ) {
md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len); md = md_open( algo, 0 );
hash_public_cert( md, c->list->pkt->pkt.public_cert );
if( sig->sig_class != 0x20 )
md_write( md, n1->pkt->pkt.user_id->name,
n1->pkt->pkt.user_id->len);
} }
else { else {
log_error("invalid parent packet for sigclass 0x10\n"); log_error("invalid parent packet for sigclass %02x\n",
sig->sig_class);
return G10ERR_SIG_CLASS; return G10ERR_SIG_CLASS;
} }
#endif
return check_key_signature( c->list, node, NULL );
} }
else { else {
log_error("invalid root packet for sigclass 0x10\n"); log_error("invalid root packet for sigclass %02x\n",
sig->sig_class);
return G10ERR_SIG_CLASS; return G10ERR_SIG_CLASS;
} }
} }
@ -374,7 +383,13 @@ list_node( CTX c, KBNODE node )
datestr_from_pkc( pkc ) ); datestr_from_pkc( pkc ) );
/* and now list all userids with their signatures */ /* and now list all userids with their signatures */
for( node = node->next; node; node = node->next ) { for( node = node->next; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID ) { if( any != 2 && node->pkt->pkttype == PKT_SIGNATURE ) {
if( !any )
putchar('\n');
list_node(c, node );
any = 1;
}
else if( node->pkt->pkttype == PKT_USER_ID ) {
KBNODE n; KBNODE n;
if( any ) if( any )
@ -389,10 +404,10 @@ list_node( CTX c, KBNODE node )
if( n->pkt->pkttype == PKT_SIGNATURE ) if( n->pkt->pkttype == PKT_SIGNATURE )
list_node(c, n ); list_node(c, n );
} }
any=1; any=2;
} }
} }
if( !any ) if( any != 2 )
printf("ERROR: no user id!\n"); printf("ERROR: no user id!\n");
} }
else if( node->pkt->pkttype == PKT_SECRET_CERT ) { else if( node->pkt->pkttype == PKT_SECRET_CERT ) {
@ -423,7 +438,10 @@ list_node( CTX c, KBNODE node )
if( !opt.list_sigs ) if( !opt.list_sigs )
return; return;
fputs("sig", stdout); if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
fputs("rev", stdout);
else
fputs("sig", stdout);
if( opt.check_sigs ) { if( opt.check_sigs ) {
fflush(stdout); fflush(stdout);
switch( (rc2=do_check_sig( c, node )) ) { switch( (rc2=do_check_sig( c, node )) ) {

View File

@ -99,7 +99,6 @@ typedef struct {
byte hdrbytes; /* number of header bytes */ byte hdrbytes; /* number of header bytes */
byte version; byte version;
byte pubkey_algo; /* algorithm used for public key scheme */ byte pubkey_algo; /* algorithm used for public key scheme */
md_filter_context_t mfx;
ulong local_id; /* internal use, valid if > 0 */ ulong local_id; /* internal use, valid if > 0 */
union { union {
struct { struct {

View File

@ -592,14 +592,6 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
unsigned short valid_period; unsigned short valid_period;
int is_v4=0; int is_v4=0;
if( pkttype == PKT_PUBLIC_CERT ) {
pkt->pkt.public_cert->mfx.md = md_open(DIGEST_ALGO_MD5, 0);
md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_RMD160);
md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_SHA1);
pkt->pkt.public_cert->mfx.maxbuf_size = 1;
md_write(pkt->pkt.public_cert->mfx.md, hdr, hdrlen);
iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx );
}
if( pktlen < 12 ) { if( pktlen < 12 ) {
log_error("packet(%d) too short\n", pkttype); log_error("packet(%d) too short\n", pkttype);
@ -765,8 +757,6 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
leave: leave:
if( pkttype == PKT_PUBLIC_CERT )
iobuf_pop_filter( inp, md_filter, &pkt->pkt.public_cert->mfx );
skip_rest(inp, pktlen); skip_rest(inp, pktlen);
return 0; return 0;
} }

View File

@ -167,7 +167,24 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
{ {
int rc; int rc;
switch( trustlevel ) { if( (trustlevel & TRUST_FLAG_REVOKED) ) {
char *answer;
int yes;
log_info("key has beed revoked!\n");
if( opt.batch )
return 0;
answer = tty_get("Use this key anyway? ");
tty_kill_prompt();
yes = answer_is_yes(answer);
m_free(answer);
if( !yes )
return 0;
}
switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */ case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record( pkc ); rc = insert_trust_record( pkc );
if( rc ) { if( rc ) {
@ -184,7 +201,7 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
return do_we_trust( pkc, trustlevel ); return do_we_trust( pkc, trustlevel );
case TRUST_EXPIRED: case TRUST_EXPIRED:
log_error("trust has expired: NOT yet implemented\n"); log_info("trust has expired: NOT yet implemented\n");
return 0; /* no */ return 0; /* no */
case TRUST_UNDEFINED: case TRUST_UNDEFINED:

View File

@ -152,6 +152,7 @@ gen_revoke( const char *uname )
} }
afx.what = 1; afx.what = 1;
afx.hdrlines = "Comment: A revocation certificate should follow\n";
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
if( opt.compress ) if( opt.compress )
iobuf_push_filter( out, compress_filter, &zfx ); iobuf_push_filter( out, compress_filter, &zfx );

View File

@ -183,7 +183,9 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
/**************** /****************
* check the signature pointed to by NODE. This is a key signatures * check the signature pointed to by NODE. This is a key signatures.
* If the function detects a elf signature, it uses the PKC from
* NODE and does not read the any public key.
*/ */
int int
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
@ -198,7 +200,6 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
if( is_selfsig ) if( is_selfsig )
*is_selfsig = 0; *is_selfsig = 0;
assert( node->pkt->pkttype == PKT_SIGNATURE ); assert( node->pkt->pkttype == PKT_SIGNATURE );
assert( (node->pkt->pkt.signature->sig_class&~3) == 0x10 );
assert( root->pkt->pkttype == PKT_PUBLIC_CERT ); assert( root->pkt->pkttype == PKT_PUBLIC_CERT );
pkc = root->pkt->pkt.public_cert; pkc = root->pkt->pkt.public_cert;
@ -213,27 +214,36 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
if( (rc=check_digest_algo(algo)) ) if( (rc=check_digest_algo(algo)) )
return rc; return rc;
unode = find_prev_kbnode( root, node, PKT_USER_ID ); if( sig->sig_class == 0x20 ) {
if( unode ) {
PKT_user_id *uid = unode->pkt->pkt.user_id;
if( is_selfsig ) {
u32 keyid[2];
keyid_from_pkc( pkc, keyid );
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
*is_selfsig = 1;
}
md = md_open( algo, 0 ); md = md_open( algo, 0 );
hash_public_cert( md, pkc ); hash_public_cert( md, pkc );
md_write( md, uid->name, uid->len );
rc = do_check( pkc, sig, md ); rc = do_check( pkc, sig, md );
md_close(md); md_close(md);
} }
else { else {
log_error("no user id for key signature packet\n"); unode = find_prev_kbnode( root, node, PKT_USER_ID );
rc = G10ERR_SIG_CLASS;
if( unode ) {
PKT_user_id *uid = unode->pkt->pkt.user_id;
u32 keyid[2];
keyid_from_pkc( pkc, keyid );
md = md_open( algo, 0 );
hash_public_cert( md, pkc );
md_write( md, uid->name, uid->len );
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
if( is_selfsig )
*is_selfsig = 1;
rc = do_check( pkc, sig, md );
}
else
rc = signature_check( sig, md );
md_close(md);
}
else {
log_error("no user id for key signature packet\n");
rc = G10ERR_SIG_CLASS;
}
} }
return rc; return rc;

View File

@ -987,6 +987,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 ); assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 );
md = md_open( digest_algo, 0 ); md = md_open( digest_algo, 0 );
/* hash the public key certificate and the user id */ /* hash the public key certificate and the user id */
hash_public_cert( md, pkc ); hash_public_cert( md, pkc );
if( sigclass != 0x20 ) if( sigclass != 0x20 )

View File

@ -380,8 +380,10 @@ dump_record( ulong rnum, TRUSTREC *rec, FILE *fp )
fputs(", (none)", fp ); fputs(", (none)", fp );
else if( rec->r.dir.no_sigs == 2 ) else if( rec->r.dir.no_sigs == 2 )
fputs(", (invalid)", fp ); fputs(", (invalid)", fp );
else if( rec->r.dir.no_sigs ) else if( rec->r.dir.no_sigs == 3 )
fputs(", (revoked)", fp ); fputs(", (revoked)", fp );
else if( rec->r.dir.no_sigs )
fputs(", (??)", fp );
putc('\n', fp); putc('\n', fp);
break; break;
case RECTYPE_KEY: fprintf(fp, "key keyid=%08lX, own=%lu, ownertrust=%02x\n", case RECTYPE_KEY: fprintf(fp, "key keyid=%08lX, own=%lu, ownertrust=%02x\n",
@ -1084,17 +1086,19 @@ do_list_path( TRUST_INFO *stack, int depth, int max_depth,
* some of them are bad? * some of them are bad?
*/ */
static int static int
check_sigs( KBNODE keyblock, int *selfsig_okay ) check_sigs( KBNODE keyblock, int *selfsig_okay, int *revoked )
{ {
KBNODE kbctx;
KBNODE node; KBNODE node;
int rc; int rc;
LOCAL_ID_INFO *dups = NULL; LOCAL_ID_INFO *dups = NULL;
*selfsig_okay = 0; *selfsig_okay = 0;
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx,0)) ; ) { *revoked = 0;
for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_SIGNATURE if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
|| node->pkt->pkt.signature->sig_class == 0x20
|| node->pkt->pkt.signature->sig_class == 0x30) ) {
int selfsig; int selfsig;
rc = check_key_signature( keyblock, node, &selfsig ); rc = check_key_signature( keyblock, node, &selfsig );
if( !rc ) { if( !rc ) {
@ -1106,13 +1110,18 @@ check_sigs( KBNODE keyblock, int *selfsig_okay )
node->flag |= 2; /* mark signature valid */ node->flag |= 2; /* mark signature valid */
*selfsig_okay = 1; *selfsig_okay = 1;
} }
else if( node->pkt->pkt.signature->sig_class == 0x20 )
*revoked = 1;
else else
node->flag |= 1; /* mark signature valid */ node->flag |= 1; /* mark signature valid */
if( !dups )
dups = new_lid_table(); if( node->pkt->pkt.signature->sig_class != 0x20 ) {
if( ins_lid_table_item( dups, if( !dups )
node->pkt->pkt.signature->local_id, 0) ) dups = new_lid_table();
node->flag |= 4; /* mark as duplicate */ if( ins_lid_table_item( dups,
node->pkt->pkt.signature->local_id, 0) )
node->flag |= 4; /* mark as duplicate */
}
} }
if( DBG_TRUST ) if( DBG_TRUST )
log_debug("trustdb: sig from %08lX(%lu): %s%s\n", log_debug("trustdb: sig from %08lX(%lu): %s%s\n",
@ -1138,10 +1147,9 @@ build_sigrecs( ulong pubkeyid )
PUBKEY_FIND_INFO finfo=NULL; PUBKEY_FIND_INFO finfo=NULL;
KBPOS kbpos; KBPOS kbpos;
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBNODE kbctx;
KBNODE node; KBNODE node;
int rc=0; int rc=0;
int i, selfsig; int i, selfsig, revoked;
ulong rnum, rnum2; ulong rnum, rnum2;
ulong first_sigrec = 0; ulong first_sigrec = 0;
@ -1173,7 +1181,7 @@ build_sigrecs( ulong pubkeyid )
goto leave; goto leave;
} }
/* check all key signatures */ /* check all key signatures */
rc = check_sigs( keyblock, &selfsig ); rc = check_sigs( keyblock, &selfsig, &revoked );
if( rc ) { if( rc ) {
log_error("build_sigrecs: check_sigs failed\n" ); log_error("build_sigrecs: check_sigs failed\n" );
goto leave; goto leave;
@ -1184,7 +1192,12 @@ build_sigrecs( ulong pubkeyid )
rc = G10ERR_BAD_CERT; rc = G10ERR_BAD_CERT;
goto leave; goto leave;
} }
update_no_sigs( pubkeyid, 0 ); /* assume we have sigs */ if( revoked ) {
log_info("build_sigrecs: key has been revoked\n" );
update_no_sigs( pubkeyid, 3 );
}
else
update_no_sigs( pubkeyid, 0 ); /* assume we have sigs */
/* valid key signatures are now marked; we can now build the /* valid key signatures are now marked; we can now build the
* sigrecs */ * sigrecs */
@ -1192,7 +1205,7 @@ build_sigrecs( ulong pubkeyid )
rec.rectype = RECTYPE_SIG; rec.rectype = RECTYPE_SIG;
i = 0; i = 0;
rnum = rnum2 = 0; rnum = rnum2 = 0;
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { for( node=keyblock; node; node = node->next ) {
/* insert sigs which are not a selfsig nor a duplicate */ /* insert sigs which are not a selfsig nor a duplicate */
if( (node->flag & 1) && !(node->flag & 4) ) { if( (node->flag & 1) && !(node->flag & 4) ) {
assert( node->pkt->pkttype == PKT_SIGNATURE ); assert( node->pkt->pkttype == PKT_SIGNATURE );
@ -1272,7 +1285,7 @@ build_sigrecs( ulong pubkeyid )
} }
} }
else else
update_no_sigs( pubkeyid, 1 ); /* no signatures */ update_no_sigs( pubkeyid, revoked? 3:1 ); /* no signatures */
leave: leave:
m_free( finfo ); m_free( finfo );
@ -1385,6 +1398,7 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
int marginal, fully; int marginal, fully;
int fully_needed = opt.completes_needed; int fully_needed = opt.completes_needed;
int marginal_needed = opt.marginals_needed; int marginal_needed = opt.marginals_needed;
unsigned tflags = 0;
assert( fully_needed > 0 && marginal_needed > 1 ); assert( fully_needed > 0 && marginal_needed > 1 );
@ -1400,10 +1414,14 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
if( !rc ) /* and read again */ if( !rc ) /* and read again */
rc = read_record( pubkeyid, dr, RECTYPE_DIR ); rc = read_record( pubkeyid, dr, RECTYPE_DIR );
} }
if( dr->r.dir.no_sigs == 3 )
tflags |= TRUST_FLAG_REVOKED;
if( !rc && !dr->r.dir.sigrec ) { if( !rc && !dr->r.dir.sigrec ) {
/* See wether this is our own key */ /* See wether this is our own key */
if( !qry_lid_table_flag( ultikey_table, pubkeyid, NULL ) ) { if( !qry_lid_table_flag( ultikey_table, pubkeyid, NULL ) ) {
*trustlevel = TRUST_ULTIMATE; *trustlevel = tflags | TRUST_ULTIMATE;
return 0; return 0;
} }
else else
@ -1442,7 +1460,7 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
if( tsl->dup ) if( tsl->dup )
continue; continue;
if( tsl->seg[0].trust == TRUST_ULTIMATE ) { if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
*trustlevel = TRUST_ULTIMATE; /* our own key */ *trustlevel = tflags | TRUST_ULTIMATE; /* our own key */
break; break;
} }
if( tsl->seg[0].trust == TRUST_FULLY ) { if( tsl->seg[0].trust == TRUST_FULLY ) {
@ -1453,12 +1471,12 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel )
marginal++; marginal++;
if( fully >= fully_needed ) { if( fully >= fully_needed ) {
*trustlevel = TRUST_FULLY; *trustlevel = tflags | TRUST_FULLY;
break; break;
} }
} }
if( !tsl && marginal >= marginal_needed ) if( !tsl && marginal >= marginal_needed )
*trustlevel = TRUST_MARGINAL; *trustlevel = tflags | TRUST_MARGINAL;
/* cache the tslist */ /* cache the tslist */
if( last_trust_web_key ) { if( last_trust_web_key ) {

View File

@ -22,14 +22,17 @@
#define G10_TRUSTDB_H #define G10_TRUSTDB_H
/* Trust values mus be sorted in ascending order */ /* Trust values must be sorted in ascending order */
#define TRUST_MASK 15
#define TRUST_UNKNOWN 0 /* not yet calculated */ #define TRUST_UNKNOWN 0 /* not yet calculated */
#define TRUST_EXPIRED 1 /* calculation may be invalid */ #define TRUST_EXPIRED 1 /* calculation may be invalid */
#define TRUST_UNDEFINED 2 /* not enough informations for calculation */ #define TRUST_UNDEFINED 2 /* not enough informations for calculation */
#define TRUST_NEVER 3 /* never trusted this pubkey */ #define TRUST_NEVER 3 /* never trust this pubkey */
#define TRUST_MARGINAL 4 /* marginally trusted */ #define TRUST_MARGINAL 4 /* marginally trusted */
#define TRUST_FULLY 5 /* fully trusted */ #define TRUST_FULLY 5 /* fully trusted */
#define TRUST_ULTIMATE 6 /* ultimately trusted */ #define TRUST_ULTIMATE 6 /* ultimately trusted */
/* trust values not covered by the mask */
#define TRUST_FLAG_REVOKED 32
/*-- trustdb.c --*/ /*-- trustdb.c --*/

View File

@ -5,7 +5,7 @@
CFLAGS = -O -Wall CFLAGS = -O -Wall
EXTRA_DIST = README algorithm.doc ChangeLog example.c EXTRA_DIST = README algorithm.doc ChangeLog example.c
# I found no other easy way to use this only if zlib is neede # I found no other easy way to use this only if zlib is neede
# doing this with SUBDIR = @xxx@ in the top Makefile.am does not # doing this with SUBDIR = @xxx@ in the top Makefile.am does not