aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shaw <[email protected]>2001-12-21 21:02:05 +0000
committerDavid Shaw <[email protected]>2001-12-21 21:02:05 +0000
commitca058399b04fedd7dcd203447e0e59080c33099e (patch)
tree42912f1dc8b7cbd7eddacf3644440f46d8a3cd67
parent* distfiles: Removed those files which which automake installs by (diff)
downloadgnupg-ca058399b04fedd7dcd203447e0e59080c33099e.tar.gz
gnupg-ca058399b04fedd7dcd203447e0e59080c33099e.zip
Nonrevocable key signature support via "nrsign". These sigs can expire,
but cannot be revoked. Any revocation certificates for them are ignored.
-rw-r--r--g10/ChangeLog24
-rw-r--r--g10/build-packet.c5
-rw-r--r--g10/g10.c11
-rw-r--r--g10/keyedit.c71
-rw-r--r--g10/keygen.c4
-rw-r--r--g10/packet.h2
-rw-r--r--g10/parse-packet.c1
-rw-r--r--g10/revoke.c2
-rw-r--r--g10/sign.c6
-rw-r--r--g10/trustdb.c22
10 files changed, 106 insertions, 42 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 14ab65c44..a29c77318 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,27 @@
+2001-12-21 David Shaw <[email protected]>
+
+ * parse-packet.c (can_handle_critical): Can handle critical
+ revocation subpackets now.
+
+ * trustdb.c (mark_usable_uid_certs): Disregard revocations for
+ nonrevocable sigs. Note that this allows a newer revocable
+ signature to override an older nonrevocable signature.
+
+ * sign.c (make_keysig_packet): add a duration field and change all
+ callers. This makes make_keysig_packet closer to
+ write_signature_packets and removes some duplicated expiration
+ code.
+
+ * keyedit.c (keyedit_menu, menu_revsig, sign_uids,
+ sign_mk_attrib): Add nrsign command, don't allow revoking a
+ nonrevocable signature,
+
+ * g10.c (main): Add --nrsign option to nonrevocably sign a key
+ from the command line.
+
+ * build-packet.c (build_sig_subpkt_from_sig): Comment to explain
+ the use of CRITICAL.
+
2001-12-21 Werner Koch <[email protected]>
* g10.c. options.h : New option --show-keyring
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 2025c4091..ae33b9c04 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -900,6 +900,11 @@ build_sig_subpkt_from_sig( PKT_signature *sig )
buf[1] = (u >> 16) & 0xff;
buf[2] = (u >> 8) & 0xff;
buf[3] = u & 0xff;
+
+ /* Mark this CRITICAL, so if any implementation doesn't
+ understand sigs that can expire, it'll just disregard this
+ sig altogether. */
+
build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
buf, 4 );
}
diff --git a/g10/g10.c b/g10/g10.c
index 9b949b3d5..f594069c0 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -78,6 +78,7 @@ enum cmd_and_opt_values { aNull = 0,
aSignSym,
aSignKey,
aLSignKey,
+ aNRSignKey,
aListPackets,
aEditKey,
aDeleteKey,
@@ -278,6 +279,7 @@ static ARGPARSE_OPTS opts[] = {
N_("remove key from the secret keyring")},
{ aSignKey, "sign-key" ,256, N_("sign a key")},
{ aLSignKey, "lsign-key" ,256, N_("sign a key locally")},
+ { aNRSignKey, "nrsign-key" ,256, N_("sign a key non-revocably")},
{ aEditKey, "edit-key" ,256, N_("sign or edit a key")},
{ aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
{ aExport, "export" , 256, N_("export keys") },
@@ -889,6 +891,7 @@ main( int argc, char **argv )
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
case aSignKey: set_cmd( &cmd, aSignKey); break;
case aLSignKey: set_cmd( &cmd, aLSignKey); break;
+ case aNRSignKey: set_cmd( &cmd, aNRSignKey); break;
case aStore: set_cmd( &cmd, aStore); break;
case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
case aClearsign: set_cmd( &cmd, aClearsign); break;
@@ -1580,6 +1583,14 @@ main( int argc, char **argv )
m_free(username);
break;
+ case aNRSignKey:
+ if( argc != 1 )
+ wrong_args(_("--nrsign-key user-id"));
+ username = make_username( fname );
+ keyedit_menu(fname, locusr, NULL, 3 );
+ m_free(username);
+ break;
+
case aEditKey: /* Edit a key signature */
if( !argc )
wrong_args(_("--edit-key user-id [commands]"));
diff --git a/g10/keyedit.c b/g10/keyedit.c
index c30cd1d7b..ef4854b51 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -75,16 +75,11 @@ static int enable_disable_key( KBNODE keyblock, int disable );
#define NODFLG_SELKEY (1<<9) /* indicate the selected key */
#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
-
struct sign_attrib {
- int non_exportable;
- u32 duration;
+ int non_exportable,non_revocable;
struct revocation_reason_info *reason;
};
-
-
-
/****************
* Print information about a signature, check it and return true
* if the signature is okay. NODE must be a signature packet.
@@ -241,20 +236,15 @@ sign_mk_attrib( PKT_signature *sig, void *opaque )
byte buf[8];
if( attrib->non_exportable ) {
+ sig->flags.exportable=0;
buf[0] = 0; /* not exportable */
build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
}
- if(attrib->duration>0) {
- buf[0]=(attrib->duration >> 24) & 0xff;
- buf[1]=(attrib->duration >> 16) & 0xff;
- buf[2]=(attrib->duration >> 8) & 0xff;
- buf[3]=attrib->duration & 0xff;
- /* Mark this CRITICAL, so if any implementation doesn't
- understand sigs that can expire, it'll just disregard this
- sig altogether. */
- build_sig_subpkt( sig, SIGSUBPKT_SIG_EXPIRE | SIGSUBPKT_FLAG_CRITICAL,
- buf, 4 );
+ if( attrib->non_revocable ) {
+ sig->flags.revocable=0;
+ buf[0] = 0; /* not revocable */
+ build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
}
if( attrib->reason )
@@ -271,7 +261,8 @@ sign_mk_attrib( PKT_signature *sig, void *opaque )
* if some user_ids are marked those will be signed.
*/
static int
-sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
+sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
+ int local , int nonrevocable )
{
int rc = 0;
int class=0;
@@ -500,6 +491,10 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
tty_printf(
_("\nThe signature will be marked as non-exportable.\n"));
+ if( nonrevocable )
+ tty_printf(
+ _("\nThe signature will be marked as non-revocable.\n"));
+
switch(class)
{
case 0x11:
@@ -537,10 +532,10 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
assert( primary_pk );
memset( &attrib, 0, sizeof attrib );
attrib.non_exportable = local;
- attrib.duration = duration;
+ attrib.non_revocable = nonrevocable;
node->flag &= ~NODFLG_MARK_A;
- /* we force createion of a v4 signature for local
+ /* we force creation of a v4 signature for local
* signatures, otherwise we would not generate the
* subpacket with v3 keys and the signature becomes
* exportable */
@@ -549,8 +544,8 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
NULL,
sk,
class, 0, force_v4?4:0,
- timestamp, sign_mk_attrib,
- &attrib );
+ timestamp, duration,
+ sign_mk_attrib, &attrib );
if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc));
goto leave;
@@ -753,7 +748,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, cmdPRIMARY,
+ cmdLSIGN, cmdNRSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, cmdPRIMARY,
cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY,
cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
@@ -780,6 +775,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
{ N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") },
{ N_("s") , cmdSIGN , 0,1,1, NULL },
{ N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") },
+ { N_("nrsign") , cmdNRSIGN , 0,1,1, N_("sign the key non-revocably") },
{ N_("debug") , cmdDEBUG , 0,0,0, NULL },
{ N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") },
{ N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") },
@@ -826,7 +822,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
if( sign_mode ) {
commands = NULL;
- append_to_strlist( &commands, sign_mode == 1? "sign":"lsign" );
+ append_to_strlist( &commands, sign_mode == 1? "sign":
+ sign_mode == 2?"lsign":"nrsign" );
have_commands = 1;
}
@@ -984,6 +981,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
case cmdSIGN: /* sign (only the public key) */
case cmdLSIGN: /* sign (only the public key) */
+ case cmdNRSIGN: /* sign (only the public key) */
if( pk->is_revoked )
{
tty_printf(_("Key is revoked.\n"));
@@ -1007,7 +1005,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
break;
}
}
- if( !sign_uids( keyblock, locusr, &modified, cmd == cmdLSIGN )
+ if( !sign_uids( keyblock, locusr, &modified,
+ cmd == cmdLSIGN , cmd == cmdNRSIGN )
&& sign_mode )
goto do_cmd_save;
break;
@@ -1526,7 +1525,7 @@ menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock )
sec_where = NULL;
assert(pk && sk );
- rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0,
+ rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
keygen_add_std_prefs, pk );
free_secret_key( sk );
if( rc ) {
@@ -1821,11 +1820,11 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
/* create new self signature */
if( mainkey )
rc = make_keysig_packet( &newsig, main_pk, uid, NULL,
- sk, 0x13, 0, 0, 0,
+ sk, 0x13, 0, 0, 0, 0,
keygen_add_std_prefs, main_pk );
else
rc = make_keysig_packet( &newsig, main_pk, NULL, sub_pk,
- sk, 0x18, 0, 0, 0,
+ sk, 0x18, 0, 0, 0, 0,
keygen_add_key_expire, sub_pk );
if( rc ) {
log_error("make_keysig_packet failed: %s\n",
@@ -2225,9 +2224,9 @@ ask_revoke_sig( KBNODE keyblock, KBNODE node )
(ulong)sig->keyid[1], datestr_from_sig(sig) );
if( cpr_get_answer_is_yes("ask_revoke_sig.one",
- _("Create a revocation certificate for this signature? (y/N)")) ) {
- node->flag |= NODFLG_MARK_A;
- unode->flag |= NODFLG_MARK_A;
+ _("Create a revocation certificate for this signature? (y/N)")) ) {
+ node->flag |= NODFLG_MARK_A;
+ unode->flag |= NODFLG_MARK_A;
}
}
@@ -2263,9 +2262,11 @@ menu_revsig( KBNODE keyblock )
&& ((sig = node->pkt->pkt.signature),
!seckey_available(sig->keyid) ) ) {
if( (sig->sig_class&~3) == 0x10 ) {
- tty_printf(_(" signed by %08lX at %s\n"),
- (ulong)sig->keyid[1], datestr_from_sig(sig) );
- node->flag |= NODFLG_SELSIG;
+ tty_printf(_(" signed by %08lX at %s%s\n"),
+ (ulong)sig->keyid[1], datestr_from_sig(sig),
+ sig->flags.revocable?"":" (not revocable)");
+ if(sig->flags.revocable)
+ node->flag |= NODFLG_SELSIG;
}
else if( sig->sig_class == 0x30 ) {
tty_printf(_(" revoked by %08lX at %s\n"),
@@ -2342,7 +2343,7 @@ menu_revsig( KBNODE keyblock )
unode->pkt->pkt.user_id,
NULL,
sk,
- 0x30, 0, 0, 0,
+ 0x30, 0, 0, 0, 0,
sign_mk_attrib,
&attrib );
free_secret_key(sk);
@@ -2405,7 +2406,7 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
node->flag &= ~NODFLG_SELKEY;
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
- 0x28, 0, 0, 0,
+ 0x28, 0, 0, 0, 0,
sign_mk_attrib, &attrib );
free_secret_key(sk);
if( rc ) {
diff --git a/g10/keygen.c b/g10/keygen.c
index f79a4a664..80a52b4ac 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -389,7 +389,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
cache_public_key (pk);
/* and make the signature */
- rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0,
+ rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
keygen_add_std_prefs, pk );
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
@@ -438,7 +438,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
/* and make the signature */
oduap.usage = use;
oduap.pk = subpk;
- rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0,
+ rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0, 0,
keygen_add_key_flags_and_expire, &oduap );
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
diff --git a/g10/packet.h b/g10/packet.h
index 0bddfe41b..de18d9695 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -437,7 +437,7 @@ int write_comment( IOBUF out, const char *s );
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
PKT_user_id *uid, PKT_public_key *subpk,
PKT_secret_key *sk, int sigclass, int digest_algo,
- int sigversion, u32 timestamp,
+ int sigversion, u32 timestamp, u32 duration,
int (*mksubpkt)(PKT_signature *, void *),
void *opaque );
int update_keysig_packet( PKT_signature **ret_sig,
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 5f2bf4ec5..1de7c85c6 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -968,6 +968,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
case SIGSUBPKT_SIG_EXPIRE:
case SIGSUBPKT_KEY_EXPIRE:
case SIGSUBPKT_EXPORTABLE:
+ case SIGSUBPKT_REVOCABLE:
case SIGSUBPKT_ISSUER:/* issuer key ID */
case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH:
diff --git a/g10/revoke.c b/g10/revoke.c
index 45ce6b3e0..ef3137109 100644
--- a/g10/revoke.c
+++ b/g10/revoke.c
@@ -193,7 +193,7 @@ gen_revoke( const char *uname )
iobuf_push_filter( out, armor_filter, &afx );
/* create it */
- rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, 0, 0,
+ rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, 0, 0, 0,
revocation_reason_build_cb,
reason );
if( rc ) {
diff --git a/g10/sign.c b/g10/sign.c
index 83ab54dfa..48a506901 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1012,7 +1012,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
PKT_user_id *uid, PKT_public_key *subpk,
PKT_secret_key *sk,
int sigclass, int digest_algo,
- int sigversion, u32 timestamp,
+ int sigversion, u32 timestamp, u32 duration,
int (*mksubpkt)(PKT_signature *, void *), void *opaque
)
{
@@ -1075,7 +1075,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
if(timestamp)
sig->timestamp=timestamp;
else
- sig->timestamp = make_timestamp();
+ sig->timestamp=make_timestamp();
+ if(duration)
+ sig->expiredate=sig->timestamp+duration;
sig->sig_class = sigclass;
if( sig->version >= 4 )
build_sig_subpkt_from_sig( sig );
diff --git a/g10/trustdb.c b/g10/trustdb.c
index fae540f57..9afc1bf8e 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -1056,7 +1056,27 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1])
continue;
n->flag |= (1<<10); /* mark this node as processed */
- if (sig->timestamp >= sigdate)
+
+ /* If the current signode is a nonrevocable signature, and
+ we're checking a revocation, then skip. Note that this
+ will let more recent signatures replace the nonrevocable
+ signature. Is that the proper behavior? */
+
+ if(IS_UID_REV(n->pkt->pkt.signature) &&
+ IS_UID_SIG(signode->pkt->pkt.signature) &&
+ !signode->pkt->pkt.signature->flags.revocable)
+ continue;
+
+ /* A nonrevocable signature n should always replace a
+ revocation in signode. If n is newer, then there is no
+ question. If n is older, then it should still replace
+ signode as the revocation in signode is invalid because n
+ is nonrevocable. */
+
+ if ((sig->timestamp >= sigdate) ||
+ (IS_UID_REV(signode->pkt->pkt.signature) &&
+ IS_UID_SIG(n->pkt->pkt.signature) &&
+ !n->pkt->pkt.signature->flags.revocable))
{
signode = n;
sigdate = sig->timestamp;