diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 38 | ||||
-rw-r--r-- | g10/Makefile.am | 2 | ||||
-rw-r--r-- | g10/build-packet.c | 11 | ||||
-rw-r--r-- | g10/cipher.c | 2 | ||||
-rw-r--r-- | g10/g10.c | 3 | ||||
-rw-r--r-- | g10/getkey.c | 20 | ||||
-rw-r--r-- | g10/kbnode.c | 14 | ||||
-rw-r--r-- | g10/keyedit.c | 134 | ||||
-rw-r--r-- | g10/keylist.c | 1 | ||||
-rw-r--r-- | g10/mainproc.c | 10 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/packet.h | 7 | ||||
-rw-r--r-- | g10/parse-packet.c | 7 | ||||
-rw-r--r-- | g10/ringedit.c | 5 | ||||
-rw-r--r-- | g10/sig-check.c | 3 | ||||
-rw-r--r-- | g10/sign.c | 106 | ||||
-rw-r--r-- | g10/tdbdump.c | 2 | ||||
-rw-r--r-- | g10/trustdb.c | 5 |
18 files changed, 336 insertions, 35 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index af3e65bf7..85a66e75f 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,41 @@ +2001-07-26 Werner Koch <[email protected]> + + * parse-packet.c (parse_photo_id): Reset all variables. + * getkey.c (merge_selfsigs_main): Removed checks on PHOTO_ID + because this is handled identically to a user ID. + +2001-07-06 Werner Koch <[email protected]> + + * cipher.c (write_header): Don't use MDC with --rfc1991. Suggested + by [email protected]. + +2001-07-05 Werner Koch <[email protected]> + + * g10.c, options.h: New option --preserve-permissions. + * ringedit.c (add_keyblock_resource): Use it here + (keyring_copy): and here. + + * trustdb.c (verify_own_keys): Be more silent on --quiet. + Suggested by Thomas Roessler. + * sig-check.c (check_key_signature2): Ditto. + * mainproc.c (proc_encrypted, proc_tree): Ditto + * getkey.c (lookup): Ditto. + +2001-07-04 Werner Koch <[email protected]> + + * ringedit.c (add_keyblock_resource): Restore filename in case of error. + +2001-06-25 Werner Koch <[email protected]> + + * kbnode.c (dump_kbnode): Print the signature timestamp. + + * keyedit.c (keyedit_menu): New menu point "primary". + (change_primary_uid_cb): New. + (menu_set_primary_uid): New. + * sign.c (update_keysig_packet): New. + * build-packet.c (build_sig_subpkt): Put the primary UID flag into + the hashed area. Allow update of some more packets. + 2001-06-15 Werner Koch <[email protected]> * getkey.c (merge_selfsigs): Exit gracefully when a secret key is diff --git a/g10/Makefile.am b/g10/Makefile.am index c38b9acf3..f77d8d32a 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -18,7 +18,7 @@ ## Process this file with automake to produce Makefile.in -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl +INCLUDES = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl EXTRA_DIST = OPTIONS pubring.asc options.skel OMIT_DEPENDENCIES = zlib.h zconf.h LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@ diff --git a/g10/build-packet.c b/g10/build-packet.c index 1e3776186..3a981ca5c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -748,7 +748,14 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, else if( (data = find_subpkt( sig->unhashed_data, type, &hlen, &dlen ))) found = 2; - if (found==2 && type == SIGSUBPKT_PRIV_VERIFY_CACHE) { + if (found==1 && (type == SIGSUBPKT_SIG_CREATED) ) { + unused = delete_sig_subpkt (sig->hashed_data, type); + assert (unused); + found = 0; + } + else if (found==2 && ( type == SIGSUBPKT_PRIV_VERIFY_CACHE + || type == SIGSUBPKT_ISSUER + ) ) { unused = delete_sig_subpkt (sig->unhashed_data, type); assert (unused); found = 0; @@ -773,6 +780,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, case SIGSUBPKT_NOTATION: case SIGSUBPKT_POLICY: case SIGSUBPKT_REVOC_REASON: + case SIGSUBPKT_PRIMARY_UID: hashed = 1; break; default: hashed = 0; break; } @@ -842,6 +850,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, /**************** * Put all the required stuff from SIG into subpackets of sig. + * Hmmm, should we delete those subpackets which are in a wrong area? */ void build_sig_subpkt_from_sig( PKT_signature *sig ) diff --git a/g10/cipher.c b/g10/cipher.c index 6ad204cc4..fbee543be 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -54,7 +54,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a ) log_fatal("unsupported blocksize %u\n", blocksize ); if( blocksize != 8 ) use_mdc = 1; /* enable it for all modern ciphers */ - if( opt.rfc2440 ) + if( opt.rfc2440 || opt.rfc1991 ) use_mdc = 0; /* override - rfc2440 does not know about MDC */ memset( &ed, 0, sizeof ed ); @@ -206,6 +206,7 @@ enum cmd_and_opt_values { aNull = 0, oFixedListMode, oNoSigCache, oNoSigCreateCheck, + oPreservePermissions, oEmu3DESS2KBug, /* will be removed in 1.1 */ oEmuMDEncodeBug, aTest }; @@ -404,6 +405,7 @@ static ARGPARSE_OPTS opts[] = { { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, { aDeleteSecretAndPublicKey, "delete-secret-and-public-key",256, "@" }, + { oPreservePermissions, "preserve-permissions", 0, "@"}, { oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"}, { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"}, {0} }; @@ -986,6 +988,7 @@ main( int argc, char **argv ) iobuf_enable_special_filenames (1); break; case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; + case oPreservePermissions: opt.preserve_permissions=1; break; default : pargs.err = configfp? 1:2; break; } diff --git a/g10/getkey.c b/g10/getkey.c index 96ab714b5..16306a71a 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1554,8 +1554,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) sigdate = 0; /* helper to find the latest signature in one user ID */ uiddate = 0; /* and over of all user IDs */ for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - || k->pkt->pkttype == PKT_PHOTO_ID ) { + if ( k->pkt->pkttype == PKT_USER_ID ) { if ( uidnode && signode ) fixup_uidnode ( uidnode, signode, keytimestamp ); uidnode = k; @@ -1610,8 +1609,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) uiddate = 0; /* helper to find the latest user ID */ for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - || k->pkt->pkttype == PKT_PHOTO_ID ) { + if ( k->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uid = k->pkt->pkt.user_id; if ( uid->help_key_usage && uid->created > uiddate ) { key_usage = uid->help_key_usage; @@ -1637,8 +1635,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) uiddate = 0; for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - || k->pkt->pkttype == PKT_PHOTO_ID ) { + if ( k->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uid = k->pkt->pkt.user_id; if ( uid->help_key_expire && uid->created > uiddate ) { key_expire = uid->help_key_expire; @@ -1658,8 +1655,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) uiddate = uiddate2 = 0; uidnode = uidnode2 = NULL; for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - || k->pkt->pkttype == PKT_PHOTO_ID ) { + if ( k->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uid = k->pkt->pkt.user_id; if ( uid->is_primary && uid->created > uiddate ) { uiddate = uid->created; @@ -1674,8 +1670,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) if ( uidnode ) { for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; k = k->next ) { - if ( k->pkt->pkttype == PKT_USER_ID - || k->pkt->pkttype == PKT_PHOTO_ID ) { + if ( k->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uid = k->pkt->pkt.user_id; if ( k != uidnode ) uid->is_primary = 0; @@ -2245,8 +2240,9 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ) keyid_from_sk( k->pkt->pkt.secret_key, aki ); k = get_pubkeyblock( aki ); if( !k ) { - log_info(_("key %08lX: secret key without public key " - "- skipped\n"), (ulong)aki[1] ); + if (!opt.quiet) + log_info(_("key %08lX: secret key without public key " + "- skipped\n"), (ulong)aki[1] ); goto skip; } secblock = ctx->keyblock; diff --git a/g10/kbnode.c b/g10/kbnode.c index 261a2b4da..b2b26a0b9 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -164,9 +164,10 @@ find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ) { KBNODE n1; - for(n1=NULL ; root && root != node; root = root->next ) - if( !pkttype || root->pkt->pkttype == pkttype ) - n1 = root; + for (n1=NULL; root && root != node; root = root->next ) { + if (!pkttype ||root->pkt->pkttype == pkttype) + n1 = root; + } return n1; } @@ -184,7 +185,7 @@ find_next_kbnode( KBNODE node, int pkttype ) for( node=node->next ; node; node = node->next ) { if( !pkttype ) return node; - else if( pkttype == PKT_USER_ID + else if( pkttype == PKT_USER_ID && ( node->pkt->pkttype == PKT_PUBLIC_KEY || node->pkt->pkttype == PKT_SECRET_KEY ) ) return NULL; @@ -367,9 +368,10 @@ dump_kbnode( KBNODE node ) fputs("\"\n", stderr); } else if( node->pkt->pkttype == PKT_SIGNATURE ) { - fprintf(stderr, " class=%02x keyid=%08lX\n", + fprintf(stderr, " class=%02x keyid=%08lX ts=%lu\n", node->pkt->pkt.signature->sig_class, - (ulong)node->pkt->pkt.signature->keyid[1] ); + (ulong)node->pkt->pkt.signature->keyid[1], + (ulong)node->pkt->pkt.signature->timestamp); } else if( node->pkt->pkttype == PKT_GPG_CONTROL ) { fprintf(stderr, " ctrl=%d len=%u\n", diff --git a/g10/keyedit.c b/g10/keyedit.c index 1a948d038..8b6386f71 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -50,6 +50,7 @@ static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_delsig( KBNODE pub_keyblock ); static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ); +static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock ); static int menu_select_uid( KBNODE keyblock, int idx ); static int menu_select_key( KBNODE keyblock, int idx ); static int count_uids( KBNODE keyblock ); @@ -107,7 +108,7 @@ get_keyblock_byname( KBNODE *keyblock, KBPOS *kbpos, const char *username ) /**************** - * Print information about a signature, chek it and return true + * Print information about a signature, check it and return true * if the signature is okay. NODE must be a signature packet. */ static int @@ -566,7 +567,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, { enum cmdids { cmdNONE = 0, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, - cmdLSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, + cmdLSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, @@ -600,6 +601,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") }, { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") }, { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") }, + { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")}, { N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret " "and public key listing") }, { N_("t" ) , cmdTOGGLE , 1,0,0, NULL }, @@ -914,6 +916,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, } break; + case cmdPRIMARY: + if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) { + merge_keys_and_selfsig( keyblock ); + modified = 1; + redisplay = 1; + } + break; + case cmdPASSWD: if( change_passphrase( sec_keyblock ) ) sec_modified = 1; @@ -1630,6 +1640,126 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock ) } + +static int +change_primary_uid_cb ( PKT_signature *sig, void *opaque ) +{ + byte buf[1]; + + /* first clear all primary uid flags so that we are sure none are + * lingering around */ + delete_sig_subpkt (sig->hashed_data, SIGSUBPKT_PRIMARY_UID); + delete_sig_subpkt (sig->unhashed_data, SIGSUBPKT_PRIMARY_UID); + + /* if opaque is set,we want to set the primary id */ + if (opaque) { + buf[0] = 1; + build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 ); + } + + return 0; +} + +/* + * Set the primary uid flag for the selected UID. We will also reset + * all other primary uid flags. For this to work with have to update + * all the signature timestamps. If we would do this with the current + * time, we lose quite a lot of information, so we use a a kludge to + * do this: Just increment the timestamp by one second which is + * sufficient to updated a signature during import. + */ +static int +menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock ) +{ + PKT_secret_key *sk; /* copy of the main sk */ + PKT_public_key *main_pk; + PKT_user_id *uid; + KBNODE node; + u32 keyid[2]; + int selected; + int modified = 0; + + if ( count_selected_uids (pub_keyblock) != 1 ) { + tty_printf(_("Please select exactly one user ID.\n")); + return 0; + } + + node = find_kbnode( sec_keyblock, PKT_SECRET_KEY ); + sk = copy_secret_key( NULL, node->pkt->pkt.secret_key); + + /* Now we can actually change the self signature(s) */ + main_pk = NULL; + uid = NULL; + selected = 0; + for ( node=pub_keyblock; node; node = node->next ) { + if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) + break; /* ready */ + + if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) { + main_pk = node->pkt->pkt.public_key; + keyid_from_pk( main_pk, keyid ); + } + else if ( node->pkt->pkttype == PKT_USER_ID ) { + uid = node->pkt->pkt.user_id; + selected = node->flag & NODFLG_SELUID; + } + else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) { + PKT_signature *sig = node->pkt->pkt.signature; + if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] + && (uid && (sig->sig_class&~3) == 0x10) + && sig->version >= 4 ) { + /* this is a selfsignature which is to be replaced + * we can just ignore v3 signatures because they are + * not able to carry the primary ID flag */ + /* FIXME: We must make sure that we only have one + self-signature per user ID here (not counting + revocations) */ + PKT_signature *newsig; + PACKET *newpkt; + const byte *p; + int action; + + /* see whether this signature has the primary UID flag */ + p = parse_sig_subpkt (sig->hashed_data, + SIGSUBPKT_PRIMARY_UID, NULL ); + if ( !p ) + p = parse_sig_subpkt (sig->unhashed_data, + SIGSUBPKT_PRIMARY_UID, NULL ); + if ( p && *p ) /* yes */ + action = selected? 0 : -1; + else /* no */ + action = selected? 1 : 0; + + if (action) { + int rc = update_keysig_packet (&newsig, sig, + main_pk, uid, + sk, + change_primary_uid_cb, + action > 0? "x":NULL ); + if( rc ) { + log_error ("update_keysig_packet failed: %s\n", + g10_errstr(rc)); + free_secret_key( sk ); + return 0; + } + /* replace the packet */ + newpkt = m_alloc_clear( sizeof *newpkt ); + newpkt->pkttype = PKT_SIGNATURE; + newpkt->pkt.signature = newsig; + free_packet( node->pkt ); + m_free( node->pkt ); + node->pkt = newpkt; + modified = 1; + } + } + } + } + + free_secret_key( sk ); + return modified; +} + + /**************** * Select one user id or remove all selection if index is 0. * Returns: True if the selection changed; diff --git a/g10/keylist.c b/g10/keylist.c index 594ed4fd1..62194d823 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -667,7 +667,6 @@ reorder_keyblock (KBNODE keyblock) primary = primary2 = node; for (node=node->next; node; primary2=node, node = node->next ) { if( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PHOTO_ID || node->pkt->pkttype == PKT_PUBLIC_SUBKEY || node->pkt->pkttype == PKT_SECRET_SUBKEY ) { break; diff --git a/g10/mainproc.c b/g10/mainproc.c index c0bd9455e..4609d56f0 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -398,8 +398,10 @@ proc_encrypted( CTX c, PACKET *pkt ) { int result = 0; - print_pkenc_list( c->pkenc_list, 1 ); - print_pkenc_list( c->pkenc_list, 0 ); + if (!opt.quiet) { + print_pkenc_list ( c->pkenc_list, 1 ); + print_pkenc_list ( c->pkenc_list, 0 ); + } write_status( STATUS_BEGIN_DECRYPTION ); @@ -1272,7 +1274,7 @@ check_sig_and_print( CTX c, KBNODE node ) write_status_text( rc? STATUS_BADSIG : STATUS_GOODSIG, us ); m_free(us); - /* find an print the primary user ID */ + /* find and print the primary user ID */ for( un=keyblock; un; un = un->next ) { if( un->pkt->pkttype != PKT_USER_ID ) continue; @@ -1507,7 +1509,7 @@ proc_tree( CTX c, KBNODE node ) } else if ( c->pipemode.op == 'B' ) ; /* this is a detached signature trough the pipemode handler */ - else + else if (!opt.quiet) log_info(_("old style (PGP 2.x) signature\n")); for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) ) diff --git a/g10/options.h b/g10/options.h index 58f5f0b58..567d9201e 100644 --- a/g10/options.h +++ b/g10/options.h @@ -103,6 +103,7 @@ struct { int no_expensive_trust_checks; int no_sig_cache; int no_sig_create_check; + int preserve_permissions; } opt; diff --git a/g10/packet.h b/g10/packet.h index bfb5e9dc3..05fb24017 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -405,6 +405,13 @@ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, int sigclass, int digest_algo, int (*mksubpkt)(PKT_signature *, void *), void *opaque ); +int update_keysig_packet( PKT_signature **ret_sig, + PKT_signature *orig_sig, + PKT_public_key *pk, + PKT_user_id *uid, + PKT_secret_key *sk, + int (*mksubpkt)(PKT_signature *, void *), + void *opaque ); /*-- keygen.c --*/ PKT_user_id *generate_user_id(void); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 0e24f6b7e..15487572e 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -423,7 +423,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, off_t *retpos, rc = parse_user_id(inp, pkttype, pktlen, pkt ); break; case PKT_PHOTO_ID: - pkt->pkttype = pkttype = PKT_USER_ID; /* must fix it */ + pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */ rc = parse_photo_id(inp, pkttype, pktlen, pkt); break; case PKT_OLD_COMMENT: @@ -1625,6 +1625,11 @@ parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 30); sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen ); packet->pkt.user_id->len = strlen(packet->pkt.user_id->name); + packet->pkt.user_id->is_primary = 0; + packet->pkt.user_id->is_revoked = 0; + packet->pkt.user_id->created = 0; + packet->pkt.user_id->help_key_usage = 0; + packet->pkt.user_id->help_key_expire = 0; packet->pkt.user_id->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen); packet->pkt.user_id->photolen = pktlen; diff --git a/g10/ringedit.c b/g10/ringedit.c index f89bda35d..4499f65f4 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -292,6 +292,7 @@ add_keyblock_resource( const char *url, int force, int secret ) */ try_make_homedir( filename ); rc = G10ERR_OPEN_FILE; + *last_slash_in_filename = '/'; goto leave; } @@ -306,7 +307,7 @@ add_keyblock_resource( const char *url, int force, int secret ) } else { #ifndef HAVE_DOSISH_SYSTEM - if( secret ) { + if( secret && !opt.preserve_permissions ) { if( chmod( filename, S_IRUSR | S_IWUSR ) ) { log_error("%s: chmod failed: %s\n", filename, strerror(errno) ); @@ -1519,7 +1520,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) } /* if the new file is a secring, restrict the permissions */ #ifndef HAVE_DOSISH_SYSTEM - if( rentry->secret ) { + if( rentry->secret && !opt.preserve_permissions ) { if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) { log_error("%s: chmod failed: %s\n", tmpfname, strerror(errno) ); diff --git a/g10/sig-check.c b/g10/sig-check.c index 660919241..fe3f1c020 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -546,7 +546,8 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, md_close(md); } else { - log_info ("no subkey for subkey revocation packet\n"); + if (!opt.quiet) + log_info ("no subkey for subkey revocation packet\n"); rc = G10ERR_SIG_CLASS; } } diff --git a/g10/sign.c b/g10/sign.c index bb1f2679a..645d676af 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -24,6 +24,7 @@ #include <string.h> #include <errno.h> #include <assert.h> +#include <unistd.h> /* need sleep() */ #include "options.h" #include "packet.h" @@ -905,3 +906,108 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, } + +/**************** + * Create a new signature packet based on an existing one. + * Only user ID signatureare supportted for now. + * TODO: Merge this with make_keysig_packet. + */ +int +update_keysig_packet( PKT_signature **ret_sig, + PKT_signature *orig_sig, + PKT_public_key *pk, + PKT_user_id *uid, + PKT_secret_key *sk, + int (*mksubpkt)(PKT_signature *, void *), + void *opaque + ) +{ + PKT_signature *sig; + int rc=0; + MD_HANDLE md; + + if (!orig_sig || !pk || !uid || !sk) + return G10ERR_GENERAL; + if (orig_sig->sig_class < 0x10 || orig_sig->sig_class > 0x13 ) + return G10ERR_GENERAL; + + md = md_open( orig_sig->digest_algo, 0 ); + + /* hash the public key certificate and the user id */ + hash_public_key( md, pk ); + if( orig_sig->version >= 4 ) { + byte buf[5]; + buf[0] = 0xb4; /* indicates a userid packet */ + buf[1] = uid->len >> 24; /* always use 4 length bytes */ + buf[2] = uid->len >> 16; + buf[3] = uid->len >> 8; + buf[4] = uid->len; + md_write( md, buf, 5 ); + } + md_write( md, uid->name, uid->len ); + + /* create a new signature packet */ + sig = copy_signature (NULL, orig_sig); + if ( sig->version >= 4 && mksubpkt) + rc = (*mksubpkt)(sig, opaque); + + /* we increasethe timestamp by one second so that a future import + of this key will replace the existing one. We make sure that + we don't produce a timestamp in the future */ + sig->timestamp++; + while (sig->timestamp >= make_timestamp()) + sleep (1); + /* put the updated timestamp back into the data */ + if( sig->version >= 4 ) + build_sig_subpkt_from_sig( sig ); + + if (!rc) { + if (sig->version >= 4) + md_putc (md, sig->version); + md_putc (md, sig->sig_class); + if (sig->version < 4) { + u32 a = sig->timestamp; + md_putc( md, (a >> 24) & 0xff ); + md_putc( md, (a >> 16) & 0xff ); + md_putc( md, (a >> 8) & 0xff ); + md_putc( md, a & 0xff ); + } + else { + byte buf[6]; + size_t n; + + md_putc( md, sig->pubkey_algo ); + md_putc( md, sig->digest_algo ); + if( sig->hashed_data ) { + n = (sig->hashed_data[0] << 8) | sig->hashed_data[1]; + md_write( md, sig->hashed_data, n+2 ); + n += 6; + } + else { + md_putc( md, 0 ); /* always hash the length of the subpacket*/ + md_putc( md, 0 ); + n = 6; + } + /* add some magic */ + buf[0] = sig->version; + buf[1] = 0xff; + buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ + buf[3] = n >> 16; + buf[4] = n >> 8; + buf[5] = n; + md_write( md, buf, 6 ); + } + md_final(md); + + rc = complete_sig( sig, sk, md ); + } + + md_close (md); + if( rc ) + free_seckey_enc (sig); + else + *ret_sig = sig; + return rc; +} + + diff --git a/g10/tdbdump.c b/g10/tdbdump.c index 07e3a7dd2..d1a6b3120 100644 --- a/g10/tdbdump.c +++ b/g10/tdbdump.c @@ -328,7 +328,7 @@ list_records( ulong lid ) /**************** - * Dump the complte trustdb or only the entries of one key. + * Dump the entire trustdb or only the entries of one key. */ void list_trustdb( const char *username ) diff --git a/g10/trustdb.c b/g10/trustdb.c index 1572b27ec..cfbb8a3c9 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -574,8 +574,9 @@ verify_own_keys(void) memset( pk, 0, sizeof *pk ); rc = get_pubkey( pk, keyid ); if( rc ) { - log_info(_("key %08lX: secret key without public key - skipped\n"), - (ulong)keyid[1] ); + if (!opt.quiet) + log_info(_("key %08lX: secret key without public key " + "- skipped\n"), (ulong)keyid[1] ); goto skip; } have_pk=1; |