aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog38
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/build-packet.c11
-rw-r--r--g10/cipher.c2
-rw-r--r--g10/g10.c3
-rw-r--r--g10/getkey.c20
-rw-r--r--g10/kbnode.c14
-rw-r--r--g10/keyedit.c134
-rw-r--r--g10/keylist.c1
-rw-r--r--g10/mainproc.c10
-rw-r--r--g10/options.h1
-rw-r--r--g10/packet.h7
-rw-r--r--g10/parse-packet.c7
-rw-r--r--g10/ringedit.c5
-rw-r--r--g10/sig-check.c3
-rw-r--r--g10/sign.c106
-rw-r--r--g10/tdbdump.c2
-rw-r--r--g10/trustdb.c5
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
+
+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 );
diff --git a/g10/g10.c b/g10/g10.c
index cd4e2bf04..87f372021 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -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;