From 22f32c947298b5acf2be412cff35d5c808770cf5 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Sun, 10 Feb 2002 00:18:54 +0000 Subject: For --sig-policy-url and --cert-policy-url, clarify what is a sig and what is a cert. A sig has sigclass 0x00, 0x01, 0x02, or 0x40, and everything else is a cert. Add a "nrlsign" for nonrevocable and local key signatures. Add a --no-force-mdc to undo --force-mdc. Add a knob to force --disable-mdc/--no-disable-mdc. Off by default, of course, but is used in --pgp2 and --pgp6 modes. Allow specifying multiple users in the "Enter the user ID" loop. Enter a blank line to stop. Show each key+id as it is added. It is not illegal (though possibly silly) to have multiple policy URLs in a given signature, so print all that are present. More efficient implementation of URL-ifying code for --search on an HKP keyserver. --- g10/ChangeLog | 28 ++++++++++++++++++++++++++++ g10/cipher.c | 3 +-- g10/g10.c | 22 ++++++++++++++++++++++ g10/hkp.c | 25 +++++++++++++------------ g10/keydb.h | 4 ++++ g10/keyedit.c | 20 ++++++++++++-------- g10/keylist.c | 4 ++-- g10/mainproc.c | 5 ++++- g10/misc.c | 8 ++++++-- g10/options.h | 1 + g10/pkclist.c | 32 +++++++++++++++++++++++--------- g10/sign.c | 5 ++--- 12 files changed, 118 insertions(+), 39 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 0bcfe5dc1..79b8a3bd4 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,31 @@ +2002-02-09 David Shaw + + * misc.c (pct_expando): More comments. + + * keydb.h, sign.c (mk_notation_and_policy): Clarify what is a sig + and what is a cert. A sig has sigclass 0x00, 0x01, 0x02, or 0x40, + and everything else is a cert. + + * g10.c (main), keyedit.c (keyedit_menu): Add a "nrlsign" for + nonrevocable and local key signatures. + + * g10.c (main): Add a --no-force-mdc to undo --force-mdc. + + * options.h, g10.c (main), cipher.c (write_header): Add a knob to + --disable-mdc/--no-disable-mdc. Off by default, of course, but is + used in --pgp2 and --pgp6 modes. + + * pkclist.c (build_pk_list): Allow specifying multiple users in + the "Enter the user ID" loop. Enter a blank line to stop. Show + each key+id as it is added. + + * keylist.c (show_policy_url), mainproc.c (print_notation_data): + It is not illegal (though possibly silly) to have multiple policy + URLs in a given signature, so print all that are present. + + * hkp.c (hkp_search): More efficient implementation of URL-ifying + code. + 2002-02-04 David Shaw * main.h, misc.c (pct_expando): New function to generalize diff --git a/g10/cipher.c b/g10/cipher.c index c1cf226a8..6f89e6bc3 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -64,10 +64,9 @@ write_header( cipher_filter_context_t *cfx, IOBUF a ) if (opt.force_mdc) use_mdc = 1; - if( opt.rfc2440 || opt.rfc1991 ) + if( opt.rfc2440 || opt.rfc1991 || opt.disable_mdc ) use_mdc = 0; /* override - rfc2440 does not know about MDC */ - memset( &ed, 0, sizeof ed ); ed.len = cfx->datalen; ed.extralen = blocksize+2; diff --git a/g10/g10.c b/g10/g10.c index ecbc3b1e7..3b216462c 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -81,6 +81,7 @@ enum cmd_and_opt_values { aNull = 0, aSignKey, aLSignKey, aNRSignKey, + aNRLSignKey, aListPackets, aEditKey, aDeleteKeys, @@ -211,6 +212,9 @@ enum cmd_and_opt_values { aNull = 0, oForceV4Certs, oNoForceV4Certs, oForceMDC, + oNoForceMDC, + oDisableMDC, + oNoDisableMDC, oS2KMode, oS2KDigest, oS2KCipher, @@ -295,6 +299,7 @@ static ARGPARSE_OPTS opts[] = { { 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")}, + { aNRLSignKey, "nrlsign-key" ,256, N_("sign a key locally and 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") }, @@ -360,6 +365,9 @@ static ARGPARSE_OPTS opts[] = { { oForceV4Certs, "force-v4-certs", 0, N_("force v4 key signatures") }, { oNoForceV4Certs, "no-force-v4-certs", 0, N_("do not force v4 key signatures") }, { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") }, + { oNoForceMDC, "no-force-mdc", 0, "@" }, + { oDisableMDC, "disable-mdc", 0, N_("never use a MDC for encryption") }, + { oNoDisableMDC, "no-disable-mdc", 0, "@" }, { oDryRun, "dry-run", 0, N_("do not make any changes") }, /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */ { oUseAgent, "use-agent",0, N_("use the gpg-agent")}, @@ -921,6 +929,7 @@ main( int argc, char **argv ) case aSignKey: set_cmd( &cmd, aSignKey); break; case aLSignKey: set_cmd( &cmd, aLSignKey); break; case aNRSignKey: set_cmd( &cmd, aNRSignKey); break; + case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break; case aStore: set_cmd( &cmd, aStore); break; case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break; case aClearsign: set_cmd( &cmd, aClearsign); break; @@ -1109,6 +1118,9 @@ main( int argc, char **argv ) case oForceV4Certs: opt.force_v4_certs = 1; break; case oNoForceV4Certs: opt.force_v4_certs = 0; break; case oForceMDC: opt.force_mdc = 1; break; + case oNoForceMDC: opt.force_mdc = 0; break; + case oDisableMDC: opt.disable_mdc = 1; break; + case oNoDisableMDC: opt.disable_mdc = 0; break; case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break; case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break; @@ -1365,6 +1377,7 @@ main( int argc, char **argv ) opt.rfc1991 = 1; opt.rfc2440 = 0; opt.force_mdc = 0; + opt.disable_mdc = 1; opt.force_v4_certs = 0; opt.no_comment = 1; opt.escape_from = 1; @@ -1379,6 +1392,7 @@ main( int argc, char **argv ) if(opt.pgp6) { opt.force_mdc=0; + opt.disable_mdc=1; opt.no_comment=1; opt.escape_from=1; opt.force_v3_sigs=1; @@ -1676,6 +1690,14 @@ main( int argc, char **argv ) m_free(username); break; + case aNRLSignKey: + if( argc != 1 ) + wrong_args(_("--nrlsign-key user-id")); + username = make_username( fname ); + keyedit_menu(fname, locusr, NULL, 4 ); + m_free(username); + break; + case aEditKey: /* Edit a key signature */ if( !argc ) wrong_args(_("--edit-key user-id [commands]")); diff --git a/g10/hkp.c b/g10/hkp.c index 2549db7e7..494e42f6d 100644 --- a/g10/hkp.c +++ b/g10/hkp.c @@ -381,13 +381,13 @@ parse_hkp_index(IOBUF buffer,char *line) int hkp_search(STRLIST tokens) { - int rc=0,len=0,first=1; + int rc=0,len=0,max,first=1; unsigned int maxlen=1024,buflen=0; #ifndef __riscos__ - unsigned char *searchstr=NULL,*searchurl=NULL; + unsigned char *searchstr=NULL,*searchurl; unsigned char *request; #else - char *searchstr=NULL,*searchurl=NULL; + char *searchstr=NULL,*searchurl; char *request; #endif struct http_context hd; @@ -424,23 +424,25 @@ int hkp_search(STRLIST tokens) /* Now make it url-ish */ + max=0; len=0; + searchurl=NULL; request=searchstr; + while(*request!='\0') { - if(isalnum(*request) || *request=='-') + if(max-len<3) { - searchurl=m_realloc(searchurl,len+1); - searchurl[len++]=*request; + max+=100; + searchurl=m_realloc(searchurl,max+1); /* Note +1 for \0 */ } + + if(isalnum(*request) || *request=='-') + searchurl[len++]=*request; else if(*request==' ') - { - searchurl=m_realloc(searchurl,len+1); - searchurl[len++]='+'; - } + searchurl[len++]='+'; else { - searchurl=m_realloc(searchurl,len+3); sprintf(&searchurl[len],"%%%02X",*request); len+=3; } @@ -448,7 +450,6 @@ int hkp_search(STRLIST tokens) request++; } - searchurl=m_realloc(searchurl,len+1); searchurl[len]='\0'; request=m_alloc(strlen(opt.keyserver_host) + 100 + strlen(searchurl)); diff --git a/g10/keydb.h b/g10/keydb.h index 6bddf1065..8432c93d2 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -26,6 +26,10 @@ #include "packet.h" #include "cipher.h" +/* What qualifies as a certification (rather than a signature?) */ +#define IS_SIG(s) (((s)->sig_class==0x00) || ((s)->sig_class==0x01) || \ + ((s)->sig_class==0x02) || ((s)->sig_class==0x40)) +#define IS_CERT(s) (!IS_SIG(s)) #define IS_KEY_SIG(s) ((s)->sig_class == 0x1f) #define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10) diff --git a/g10/keyedit.c b/g10/keyedit.c index 627b61c18..db834cc74 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -753,11 +753,11 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, { enum cmdids { cmdNONE = 0, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, - cmdLSIGN, cmdNRSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, cmdPRIMARY, - cmdDEBUG, cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, - cmdDELKEY, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, - cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, - cmdUPDPREF, cmdINVCMD, cmdSHOWPHOTO, cmdNOP }; + cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY, cmdDELSIG, + cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, + cmdADDKEY, cmdDELKEY, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, + cmdPREF, cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, + cmdSETPREF, cmdUPDPREF, cmdINVCMD, cmdSHOWPHOTO, cmdNOP }; static struct { const char *name; enum cmdids id; int need_sk; @@ -781,6 +781,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, { 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_("nrlsign") , cmdNRLSIGN , 0,1,1, N_("sign the key locally and non-revocably") }, { N_("debug") , cmdDEBUG , 0,0,0, NULL }, { N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") }, { N_("addphoto"), cmdADDPHOTO , 1,1,0, N_("add a photo ID") }, @@ -832,7 +833,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, if( sign_mode ) { commands = NULL; append_to_strlist( &commands, sign_mode == 1? "sign": - sign_mode == 2?"lsign":"nrsign" ); + sign_mode == 2?"lsign": + sign_mode == 3?"nrsign":"nrlsign"); have_commands = 1; } @@ -992,6 +994,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) */ + case cmdNRLSIGN: /* sign (only the public key) */ if( pk->is_revoked ) { tty_printf(_("Key is revoked.\n")); @@ -1016,9 +1019,10 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, } } if( !sign_uids( keyblock, locusr, &modified, - cmd == cmdLSIGN , cmd == cmdNRSIGN ) + (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN), + (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN)) && sign_mode ) - goto do_cmd_save; + goto do_cmd_save; break; case cmdDEBUG: diff --git a/g10/keylist.c b/g10/keylist.c index db085943f..8fc486c5d 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -69,9 +69,9 @@ show_policy_url(PKT_signature *sig,int indent) { const byte *p; size_t len; + int seq=0; - p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len); - if(p) + while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq))) { int i; diff --git a/g10/mainproc.c b/g10/mainproc.c index 08a205b18..9bb9338ae 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -734,7 +734,10 @@ print_notation_data( PKT_signature *sig ) write_status_buffer ( STATUS_NOTATION_NAME, p , n1, 0 ); write_status_buffer ( STATUS_NOTATION_DATA, p+n1, n2, 50 ); } - if( (p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &n ) )) { + + seq=0; + + while( (p = enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &n, &seq) )) { log_info(_("Policy: ") ); print_string( log_stream(), p, n, 0 ); putc( '\n', log_stream() ); diff --git a/g10/misc.c b/g10/misc.c index 123f3a678..5c3ef12de 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -442,7 +442,8 @@ idea_cipher_warn(int show) /* The largest string we have an expando for, times two. */ #define LARGEST_EXPANDO ((MAX_FINGERPRINT_LEN*2)*2) -/* Expand %-strings */ +/* Expand %-strings. Returns a string which must be m_freed. Returns + NULL if the string cannot be expanded (too large). */ char * pct_expando(const char *string,PKT_public_key *pk) { @@ -517,7 +518,10 @@ pct_expando(const char *string,PKT_public_key *pk) break; /* Any unknown %-keys (like %i, %o, %I, and %O) are - passed through for later expansion. */ + passed through for later expansion. Note this also + handles the case where the last character in the + string is a '%' - the terminating \0 will end up here + and properly terminate the string. */ default: if(idx+2>maxlen) goto fail; diff --git a/g10/options.h b/g10/options.h index 563f7ef1a..ecbc3fe08 100644 --- a/g10/options.h +++ b/g10/options.h @@ -62,6 +62,7 @@ struct { int force_v3_sigs; int force_v4_certs; int force_mdc; + int disable_mdc; int def_digest_algo; int def_compress_algo; const char *def_secret_key; diff --git a/g10/pkclist.c b/g10/pkclist.c index 5678c99f1..a9b79815c 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -737,14 +737,14 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) } if( !any_recipients && !opt.batch ) { /* ask */ - char *answer=NULL; int have_def_rec; + char *answer=NULL; def_rec = default_recipient(); have_def_rec = !!def_rec; if( !have_def_rec ) tty_printf(_( - "You did not specify a user ID. (you may use \"-r\")\n\n")); + "You did not specify a user ID. (you may use \"-r\")\n")); for(;;) { rc = 0; m_free(answer); @@ -754,12 +754,14 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) } else { answer = cpr_get_utf8("pklist.user_id.enter", - _("Enter the user ID: ")); + _("\nEnter the user ID. End with an empty line: ")); trim_spaces(answer); cpr_kill_prompt(); } - if( !*answer ) + if( !answer || !*answer ) { + m_free(answer); break; + } if( pk ) free_public_key( pk ); pk = m_alloc_clear( sizeof *pk ); @@ -782,7 +784,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) pk_list = r; } any_recipients = 1; - break; + continue; } else { int trustlevel; @@ -796,11 +798,24 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) * in the list */ if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key(pk); pk = NULL; - log_info(_("skipped: public key " - "already set with --encrypt-to\n") ); + log_info(_("skipped: public key already set\n") ); } else { PK_LIST r; + char *p; + size_t n; + u32 keyid[2]; + + keyid_from_pk( pk, keyid); + tty_printf("Added %4u%c/%08lX %s \"", + nbits_from_pk( pk ), + pubkey_letter( pk->pubkey_algo ), + (ulong)keyid[1], + datestr_from_pk( pk ) ); + p = get_user_id( keyid, &n ); + tty_print_utf8_string( p, n ); + m_free(p); + tty_printf("\"\n"); r = m_alloc( sizeof *r ); r->pk = pk; pk = NULL; @@ -809,14 +824,13 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) pk_list = r; } any_recipients = 1; - break; + continue; } } } m_free(def_rec); def_rec = NULL; have_def_rec = 0; } - m_free(answer); if( pk ) { free_public_key( pk ); pk = NULL; diff --git a/g10/sign.c b/g10/sign.c index 7f242d7a5..57618c377 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -49,7 +49,6 @@ #define LF "\n" #endif - /**************** * Create a notation. It is assumed that the stings in STRLIST * are already checked to contain only printable data and have a valid @@ -96,14 +95,14 @@ mk_notation_and_policy( PKT_signature *sig, PKT_public_key *pk ) } /* set policy URL */ - if( (sig->sig_class==0 || sig->sig_class==1) && opt.sig_policy_url ) + if( IS_SIG(sig) && opt.sig_policy_url ) { if(sig->version<4) log_info("can't put a policy URL into v3 signatures\n"); else s=m_strdup(opt.sig_policy_url); } - else if( !(sig->sig_class==0 || sig->sig_class==1) && opt.cert_policy_url ) + else if( IS_CERT(sig) && opt.cert_policy_url ) { if(sig->version<4) log_info("can't put a policy URL into v3 key signatures\n"); -- cgit v1.2.3