diff options
author | Werner Koch <[email protected]> | 1998-11-13 19:41:41 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1998-11-13 19:41:41 +0000 |
commit | 17ea875ab0abd267eb720f8c82ac668e90cc3669 (patch) | |
tree | fc75d775f3e942991d46bee3ed596ffb4523efd6 /g10/trustdb.c | |
parent | Not yet completed changes to support PPC (diff) | |
download | gnupg-17ea875ab0abd267eb720f8c82ac668e90cc3669.tar.gz gnupg-17ea875ab0abd267eb720f8c82ac668e90cc3669.zip |
See ChangeLog ;-). Key validation should now be faster
Diffstat (limited to 'g10/trustdb.c')
-rw-r--r-- | g10/trustdb.c | 118 |
1 files changed, 80 insertions, 38 deletions
diff --git a/g10/trustdb.c b/g10/trustdb.c index c145525fa..4cdb7e8db 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -42,8 +42,6 @@ #include "i18n.h" #include "tdbio.h" -#define MAX_CERT_DEPTH 5 - #if MAX_FINGERPRINT_LEN > 20 #error Must change structure of trustdb #endif @@ -67,7 +65,7 @@ typedef struct trust_info TRUST_INFO; struct trust_info { ulong lid; byte otrust; /* ownertrust (assigned trust) */ - byte trust; /* calculated trust (validity) */ + byte trust; /* calculated trust (validity) */ }; typedef struct trust_seg_list *TRUST_SEG_LIST; @@ -806,14 +804,15 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec, continue; /* skip revoked signatures */ /* visit every signer only once (a signer may have - * signed multizple user IDs */ + * signed more than one user ID) */ if( sigs_seen && ins_lid_table_item( sigs_seen, rec.r.sig.sig[i].lid, 0) ) - continue; /* we alread have this one */ + continue; /* we already have this one */ read_record( rec.r.sig.sig[i].lid, &tmp, 0 ); if( tmp.rectype != RECTYPE_DIR ) { - log_info("oops: lid %lu: sig %lu has rectype %d" + if( tmp.rectype != RECTYPE_SDIR ) + log_info("oops: lid %lu: sig %lu has rectype %d" " - skipped\n", drec->r.dir.lid, tmp.recnum, tmp.rectype ); continue; @@ -892,7 +891,7 @@ verify_key( int max_depth, TRUSTREC *drec ) * but nothing more is known. */ static int -do_check( TRUSTREC *dr, unsigned *trustlevel ) +do_check( TRUSTREC *dr, unsigned *validity ) { if( !dr->r.dir.keylist ) { log_error(_("Ooops, no keys\n")); @@ -903,10 +902,23 @@ do_check( TRUSTREC *dr, unsigned *trustlevel ) return G10ERR_TRUSTDB; } - *trustlevel = verify_key( MAX_CERT_DEPTH, dr ); + if( tdbio_db_matches_options() + && (dr->r.dir.dirflags & DIRF_VALVALID) + && dr->r.dir.validity ) + *validity = dr->r.dir.validity; + else { + *validity = verify_key( opt.max_cert_depth, dr ); + if( (*validity & TRUST_MASK) >= TRUST_UNDEFINED + && tdbio_db_matches_options() ) { + /* update the cached validity value */ + dr->r.dir.validity = (*validity & TRUST_MASK); + dr->r.dir.dirflags |= DIRF_VALVALID; + write_record( dr ); + } + } if( dr->r.dir.dirflags & DIRF_REVOKED ) - *trustlevel |= TRUST_FLAG_REVOKED; + *validity |= TRUST_FLAG_REVOKED; return 0; } @@ -1496,7 +1508,10 @@ query_trust_info( PKT_public_key *pk ) /**************** * Enumerate all keys, which are needed to build all trust paths for * the given key. This function does not return the key itself or - * the ultimate key. + * the ultimate key (the last point in cerificate chain). Only + * certificate chains which ends up at an ultimately trusted key + * are listed. If ownertrust or validity is not NULL, the corresponding + * value for the returned LID is also returned in these variable(s). * * 1) create a void pointer and initialize it to NULL * 2) pass this void pointer by reference to this function. @@ -1505,51 +1520,73 @@ query_trust_info( PKT_public_key *pk ) * to indicate EOF. LID does contain the next key used to build the web * 4) Always call this function a last time with LID set to NULL, * so that it can free its context. + * + * Returns: -1 on EOF or the level of the returned LID */ int -enum_trust_web( void **context, ulong *lid ) +enum_cert_paths( void **context, ulong *lid, + unsigned *ownertrust, unsigned *validity ) { - #if 0 struct { int init; + TRUST_SEG_LIST tsl_head; + TRUST_SEG_LIST tsl; + int idx; } *ctx; - int rc; - int wipe=0; - TRUSTREC rec; - TRUST_INFO *tmppath; - TRUST_SEG_LIST trust_seg_list, tsl, tsl2; - PKT_public_key *pk = m_alloc_clear( sizeof *pk ); + TRUST_SEG_LIST tsl; + + if( !lid ) { /* release the context */ + if( *context ) { + TRUST_SEG_LIST tsl2; + + ctx = *context; + for(tsl = ctx->tsl_head; tsl; tsl = tsl2 ) { + tsl2 = tsl->next; + m_free( tsl ); + } + *context = NULL; + } + return -1; + } if( !*context ) { - asssert( *lid ); + TRUST_INFO *tmppath; + TRUSTREC rec; + + if( !lid ) + return -1; ctx = m_alloc_clear( sizeof *ctx ); *context = ctx; /* collect the paths */ read_record( *lid, &rec, RECTYPE_DIR ); - tmppath = m_alloc_clear( (MAX_CERT_DEPTH+1)* sizeof *tmppath ); - trust_seg_list = NULL; - collect_paths( 0, MAX_CERT_DEPTH, 1, &rec, tmppath, &trust_seg_list ); + tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath ); + tsl = NULL; + collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &tsl ); m_free( tmppath ); /* and now print them */ - for(tsl = trust_seg_list; tsl; tsl = tsl->next ) { - print_path( tsl->pathlen, tsl->path ); - } + ctx->tsl_head = tsl; + ctx->tsl = ctx->tsl_head; + ctx->idx = 0; } else ctx = *context; - if( !lid ) { /* release the context */ - if( * - /* release the list */ - for(tsl = trust_seg_list; tsl; tsl = tsl2 ) { - tsl2 = tsl->next; - m_free( tsl ); - } - trust_seg_list = NULL; - } - #endif - return -1; /* eof */ + while( ctx->tsl && ctx->idx >= tsl->pathlen ) { + ctx->tsl = ctx->tsl->next; + ctx->idx = 0; + } + tsl = ctx->tsl; + if( !tsl ) + return -1; /* eof */ + + if( ownertrust ) + *ownertrust = tsl->path[ctx->idx].otrust; + if( validity ) + *validity = tsl->path[ctx->idx].trust; + *lid = tsl->path[ctx->idx].lid; + ctx->idx++; + return ctx->idx-1; } @@ -1671,7 +1708,7 @@ query_trust_record( PKT_public_key *pk ) return get_dir_record( pk, &rec ); } -/* FIXME: Brauchen wir das?? */ + int clear_trust_checked_flag( PKT_public_key *pk ) { @@ -1682,11 +1719,14 @@ clear_trust_checked_flag( PKT_public_key *pk ) if( rc ) return rc; - if( !(rec.r.dir.dirflags & DIRF_CHECKED) ) + /* check whether they are already reset */ + if( !(rec.r.dir.dirflags & DIRF_CHECKED) + && !(rec.r.dir.dirflags & DIRF_VALVALID) ) return 0; /* reset the flag */ rec.r.dir.dirflags &= ~DIRF_CHECKED; + rec.r.dir.dirflags &= ~DIRF_VALVALID; write_record( &rec ); do_sync(); return 0; @@ -2735,6 +2775,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified ) if( rc ) rc = tdbio_cancel_transaction(); else { + drec.r.dir.dirflags |= DIRF_CHECKED; + drec.r.dir.dirflags &= ~DIRF_VALVALID; write_record( &drec ); if( modified && tdbio_is_dirty() ) *modified = 1; |