diff options
Diffstat (limited to '')
-rw-r--r-- | g10/ChangeLog | 4 | ||||
-rw-r--r-- | g10/getkey.c | 2 | ||||
-rw-r--r-- | g10/keygen.c | 5 | ||||
-rw-r--r-- | g10/mainproc.c | 4 | ||||
-rw-r--r-- | g10/ringedit.c | 43 | ||||
-rw-r--r-- | g10/signal.c | 9 | ||||
-rw-r--r-- | g10/tdbio.c | 10 | ||||
-rw-r--r-- | g10/trustdb.c | 165 |
8 files changed, 226 insertions, 16 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 38a506d9c..911554abb 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,7 @@ +Sat Oct 3 11:01:21 1998 Werner Koch ([email protected]) + + * keygen.c (ask_alogo): enable ElGamal enc-only only for addmode. + Wed Sep 30 10:15:33 1998 Werner Koch ([email protected]) * import.c (import_one): Fixed update of wrong keyblock. diff --git a/g10/getkey.c b/g10/getkey.c index eed62e916..886d53cc9 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1078,6 +1078,8 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys ) } if( !sk ) { /* free the context */ + if( c->iobuf ) + iobuf_close(c->iobuf); m_free( c ); *context = NULL; return 0; diff --git a/g10/keygen.c b/g10/keygen.c index 1d1cdbfc2..3a7582013 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -384,7 +384,8 @@ ask_algo( int *ret_v4, int addmode ) if( !addmode ) tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 ); tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 2 ); - tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 ); + if( addmode ) + tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 ); tty_printf( _(" (%d) DSA (sign only)\n"), 4 ); tty_printf( _(" (%d) ElGamal in a v3 packet\n"), 5 ); @@ -402,7 +403,7 @@ ask_algo( int *ret_v4, int addmode ) algo = PUBKEY_ALGO_ELGAMAL; break; } - else if( algo == 3 ) { + else if( algo == 3 && addmode ) { algo = PUBKEY_ALGO_ELGAMAL_E; break; } diff --git a/g10/mainproc.c b/g10/mainproc.c index dd40c10f5..e5c83287a 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -848,7 +848,9 @@ check_sig_and_print( CTX c, KBNODE node ) rc = do_check_sig(c, node, NULL ); if( !rc || rc == G10ERR_BAD_SIGN ) { - write_status( rc? STATUS_BADSIG : STATUS_GOODSIG ); + char *us = get_user_id_string( sig->keyid ); + write_status_text( rc? STATUS_BADSIG : STATUS_GOODSIG, us ); + m_free(us); log_info(rc? _("BAD signature from \"") : _("Good signature from \"")); print_keyid( stderr, sig->keyid ); diff --git a/g10/ringedit.c b/g10/ringedit.c index 6f505ef2a..ace7adc5f 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -111,13 +111,9 @@ add_keyblock_resource( const char *filename, int force, int secret ) if( i == MAX_RESOURCES ) return G10ERR_RESOURCE_LIMIT; - #if __MINGW32__ - iobuf = NULL; - #else iobuf = iobuf_open( filename ); if( !iobuf && !force ) return G10ERR_OPEN_FILE; - #endif if( !iobuf ) { iobuf = iobuf_create( filename ); @@ -129,6 +125,12 @@ add_keyblock_resource( const char *filename, int force, int secret ) log_info("%s: keyring created\n", filename ); } + #ifdef __MINGW32__ + /* must close it again */ + iobuf_close( iobuf ); + iobuf = NULL; + #endif + resource_table[i].used = 1; resource_table[i].secret = !!secret; resource_table[i].fname = m_strdup(filename); @@ -329,7 +331,7 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root ) * all others are reserved! * Note that you do not need a search prior to this function, * only a handle is needed. - * NOTE: It is not allowed to do an insert/update/delte with this + * NOTE: It is not allowed to do an insert/update/delete with this * keyblock, if you want to do this, use search/read! */ int @@ -706,7 +708,6 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) } - /**************** * Perform insert/delete/update operation. * mode 1 = insert @@ -768,10 +769,33 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) } /* create the new file */ + #ifdef __MINGW32__ + /* Here is another Windoze bug?: + * you cant rename("pubring.gpg.tmp", "pubring.gpg"); + * but rename("pubring.gpg.tmp", "pubring.aaa"); + * works. So we replace .gpg by .bak or .tmp + */ + if( strlen(rentry->fname) > 4 + && !strcmp(rentry->fname+strlen(rentry->fname)-4, ".gpg") ) { + bakfname = m_alloc( strlen( rentry->fname ) + 1 ); + strcpy(bakfname,rentry->fname); + strcpy(bakfname+strlen(rentry->fname)-4, ".bak"); + tmpfname = m_alloc( strlen( rentry->fname ) + 1 ); + strcpy(tmpfname,rentry->fname); + strcpy(tmpfname+strlen(rentry->fname)-4, ".tmp"); + } + else { /* file does not end with gpg; hmmm */ + bakfname = m_alloc( strlen( rentry->fname ) + 5 ); + strcpy(stpcpy(bakfname,rentry->fname),".bak"); + tmpfname = m_alloc( strlen( rentry->fname ) + 5 ); + strcpy(stpcpy(tmpfname,rentry->fname),".tmp"); + } + #else bakfname = m_alloc( strlen( rentry->fname ) + 2 ); strcpy(stpcpy(bakfname,rentry->fname),"~"); tmpfname = m_alloc( strlen( rentry->fname ) + 5 ); strcpy(stpcpy(tmpfname,rentry->fname),".tmp"); + #endif newfp = iobuf_create( tmpfname ); if( !newfp ) { log_error("%s: can't create: %s\n", tmpfname, strerror(errno) ); @@ -857,6 +881,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) goto leave; } /* if the new file is a secring, restrict the permissions */ + #ifndef __MINGW32__ if( rentry->secret ) { if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) { log_error("%s: chmod failed: %s\n", @@ -865,9 +890,11 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) goto leave; } } + #endif + /* rename and make backup file */ if( !rentry->secret ) { /* but not for secret keyrings */ - #if __MINGW32__ + #ifdef __MINGW32__ remove( bakfname ); #endif if( rename( rentry->fname, bakfname ) ) { @@ -877,7 +904,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) goto leave; } } - #if __MINGW32__ + #ifdef __MINGW32__ remove( rentry->fname ); #endif if( rename( tmpfname, rentry->fname ) ) { diff --git a/g10/signal.c b/g10/signal.c index c491329b4..d89b548b1 100644 --- a/g10/signal.c +++ b/g10/signal.c @@ -45,7 +45,7 @@ signal_name( int signum ) return sys_siglist[signum]; #else static char buf[20]; - sprintf( "signal %d", signum ); + sprintf(buf, "signal %d", signum ); return buf; #endif } @@ -70,7 +70,7 @@ got_usr_signal( int sig ) caught_sigusr1 = 1; } - +#ifndef __MINGW32__ static void do_sigaction( int sig, struct sigaction *nact ) { @@ -80,10 +80,12 @@ do_sigaction( int sig, struct sigaction *nact ) if( oact.sa_handler != SIG_IGN ) sigaction( sig, nact, NULL); } +#endif void init_signals() { + #ifndef __MINGW32__ struct sigaction nact; nact.sa_handler = got_fatal_signal; @@ -97,12 +99,14 @@ init_signals() do_sigaction( SIGSEGV, &nact ); nact.sa_handler = got_usr_signal; sigaction( SIGUSR1, &nact, NULL ); + #endif } void pause_on_sigusr( int which ) { + #ifndef __MINGW32__ sigset_t mask, oldmask; assert( which == 1 ); @@ -114,5 +118,6 @@ pause_on_sigusr( int which ) sigsuspend( &oldmask ); caught_sigusr1 = 0; sigprocmask( SIG_UNBLOCK, &mask, NULL ); + #endif } diff --git a/g10/tdbio.c b/g10/tdbio.c index 02950b502..ef29742fd 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -86,13 +86,17 @@ tdbio_set_dbname( const char *new_dbname, int create ) } *p = '/'; - fp =fopen( fname, "w" ); + fp =fopen( fname, "wb" ); if( !fp ) log_fatal_f( fname, _("can't create: %s\n"), strerror(errno) ); fclose(fp); m_free(db_name); db_name = fname; + #ifdef __MINGW32__ + db_fd = open( db_name, O_RDWR | O_BINARY ); + #else db_fd = open( db_name, O_RDWR ); + #endif if( db_fd == -1 ) log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) ); @@ -131,7 +135,11 @@ open_db() TRUSTREC rec; assert( db_fd == -1 ); + #ifdef __MINGW32__ + db_fd = open( db_name, O_RDWR | O_BINARY ); + #else db_fd = open( db_name, O_RDWR ); + #endif if( db_fd == -1 ) log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) ); if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) diff --git a/g10/trustdb.c b/g10/trustdb.c index 2ecc2e2bc..702ce8e70 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -410,6 +410,7 @@ verify_own_keys() rc = 0; leave: + enum_secret_keys( &enum_context, NULL, 0 ); /* free context */ free_secret_key( sk ); free_public_key( pk ); return rc; @@ -1945,6 +1946,8 @@ clear_trust_checked_flag( PKT_public_key *pk ) * Update all the info from the public keyblock, the signatures-checked * flag is reset. The key must already exist in the keydb. * Note: This function clears all keyblock flags. + * + * Implementation of this function needs a cache for tdbio record updates */ int update_trust_record( KBNODE keyblock ) @@ -1954,6 +1957,7 @@ update_trust_record( KBNODE keyblock ) TRUSTREC drec; int modified = 0; int rc = 0; + ulong recno, newrecno; clear_kbnode_flags( keyblock ); node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); @@ -1961,20 +1965,172 @@ update_trust_record( KBNODE keyblock ) rc = get_dir_record( primary_pk, &drec ); if( rc ) return rc; +#if 0 + /* fixme: start a transaction */ + /* now upate keys and user ids */ + 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; + byte fpr[MAX_FINGERPRINT_LEN]; + size_t fprlen; + TRUSTREC krec; + + fingerprint_from_pk( pk, fpr, &fprlen ); + /* do we already have this key? */ + for( recno=drec.r.dir.keylist; recno; recno = krec.r.key.next ) { + rc = tdbio_read_record( recno, &krec, RECTYPE_KEY ); + if( rc ) { + log_error("lid %lu: read key record failed: %s\n", + primary_pk->local_id, g10_errstr(rc)); + goto leave; + } + if( krec.r.key.fingerprint_len == fprlen + && !memcmp( krec.r.key.fingerprint_len, fpr, fprlen ) ) + break; + } + if( recno ) { /* yes */ + /* here we would compare/update the keyflags */ + } + else { /* no: insert this new key */ + memset( krec, 0, sizeof(krec) ); + krec.rectype = RECTYPE_KEY; + krec.r.key.pubkey_algo = pk->pubkey_algo; + krec.r.key.fingerprint_len = fprlen; + memcpy(krec.r.key.fingerprint, fpr, fprlen ); + krec.recnum = newrecno = tdbio_new_recnum(); + if( tdbio_write_record( krec ) ) { + log_error("writing key record failed\n"); + rc = G10ERR_TRUSTDB; + goto leave; + } + /* and put this new record at the end of the keylist */ + if( !(recno=drec.r.dir.keylist) ) { + /* this is the first key */ + drec.r.dir.keylist = newrecno; + modified = 1; + } + else { /* we already have key, append it to the list */ + for( ; recno; recno = krec.r.key.next ) { + rc = tdbio_read_record( recno, &krec, RECTYPE_KEY ); + if( rc ) { + log_error("lid %lu: read key record failed: %s\n", + primary_pk->local_id, g10_errstr(rc)); + goto leave; + } + } + krec.r.key.next = newrecno; + if( tdbio_write_record( krec ) ) { + log_error("writing key record failed\n"); + rc = G10ERR_TRUSTDB; + goto leave; + } + } + } /* end insert new key */ + } /* end packet type public key packet */ + else if( node->pkt->pkttype == PKT_USER_ID ) { + PKT_user_id *uid = node->pkt->pkt.user_id; + TRUSTREC urec; + byte nhash[20]; + rmd160_hash_buffer( nhash, uid->name, uid->len ); + for( recno=dir->r.dir.uidlist; recno; recno = urec->r.uid.next ) { + rc = tdbio_read_record( recno, urec, RECTYPE_UID ); + if( rc ) { + if( rc == -1 ) + rc = G10ERR_READ_FILE + log_error("lid %lu, uid %02X%02X: read error\n" + primary_pk->local_id, nhash[18], nhash[19] ); + goto leave; + } + if( !memcmp( nhash, urec->r.uid.namehash, 20 ) ) + break; + } + if( !recno ) { /* new user id */ + + } + + } + else if( node->pkt->pkttype == PKT_SIGNATURE ) { + PKT_signature *sig = node->pkt->pkt.signature; + + if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] + && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { + /* must verify this selfsignature here, so that we can + * build the preference record and validate the uid record + */ + if( !uidlist ) { + log_error("key %08lX: self-signature without user id\n", + (ulong)keyid[1] ); + } + else if( (rc = check_key_signature( keyblock, node, NULL ))) { + log_error("key %08lX, uid %02X%02X: " + "invalid self-signature: %s\n", + (ulong)keyid[1], uidlist->r.uid.namehash[18], + uidlist->r.uid.namehash[19], g10_errstr(rc) ); + rc = 0; + } + else { /* build the prefrecord */ + static struct { + sigsubpkttype_t subpkttype; + int preftype; + } prefs[] = { + { SIGSUBPKT_PREF_SYM, PREFTYPE_SYM }, + { SIGSUBPKT_PREF_HASH, PREFTYPE_HASH }, + { SIGSUBPKT_PREF_COMPR, PREFTYPE_COMPR }, + { 0, 0 } + }; + const byte *s; + size_t n; + int k, i; + assert(uidlist); + assert(!uidlist->help_pref); + uidlist->mark |= 1; /* mark valid */ + + i = 0; + for(k=0; prefs[k].subpkttype; k++ ) { + s = parse_sig_subpkt2( sig, prefs[k].subpkttype, &n ); + if( s ) { + while( n ) { + if( !i || i >= ITEMS_PER_PREF_RECORD ) { + rec = m_alloc_clear( sizeof *rec ); + rec->rectype = RECTYPE_PREF; + rec->next = uidlist->help_pref; + uidlist->help_pref = rec; + i = 0; + } + rec->r.pref.data[i++] = prefs[k].preftype; + rec->r.pref.data[i++] = *s++; + n--; + } + } + } + } + } + else if( 0 /* is revocation sig etc */ ) { + /* handle it here */ + } + else { /* not a selfsignature */ + } + } + } /* end loop over all nodes */ if( drec.r.dir.dirflags & DIRF_CHECKED ) /* <<--- FIXME: remove this! */ modified = 1; - if( modified ) { + leave: + if( rc ) + ; /* fixme: cancel transaction */ + else if( modified ) { /* reset the checked flag */ drec.r.dir.dirflags &= ~DIRF_CHECKED; rc = tdbio_write_record( &drec ); if( rc ) log_error("update_trust_record: write dir record failed: %s\n", g10_errstr(rc)); + /* fixme: commit_transaction */ } - +#endif return rc; } @@ -2004,6 +2160,11 @@ rel_mem_uidnode( u32 *keyid, int err, TRUSTREC *rec ) * * We build everything we can do at this point. We cannot build * the sig records, because their LIDs are needed and we may not have them. + * + * + * FIXME: This is too complicated: Most of the stuff is duplicated in + * update_trustdb and it will be easier to use a trust record cache instead + * of the complicated lists. */ int insert_trust_record( PKT_public_key *orig_pk ) |