diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 28 | ||||
-rw-r--r-- | g10/build-packet.c | 39 | ||||
-rw-r--r-- | g10/g10.c | 23 | ||||
-rw-r--r-- | g10/keyid.c | 4 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/pkclist.c | 19 | ||||
-rw-r--r-- | g10/revoke.c | 26 | ||||
-rw-r--r-- | g10/sign.c | 22 | ||||
-rw-r--r-- | g10/trustdb.c | 23 |
9 files changed, 151 insertions, 34 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 06588eebc..5ce79becd 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,31 @@ +2001-11-08 Werner Koch <[email protected]> + + * pkclist.c (do_edit_ownertrust): Allow to skip over keys, the non + working "show info" is now assigned to "i" + * trustdb.c (ask_ownertrust, validate_keys): Implement a real quit + here. Both are by David Shaw. + + * trustdb.c (validate_keys): Make sure next_exipire is initialized. + + * sign.c (make_keysig_packet): Use SHA-1 with v4 RSA keys. + + * g10.c, options.h : New option --[no-]froce-v4-certs. + * sign.c (make_keysig_packet): Create v4 sigs on v4 keys even with + a v3 key. Use new option. By David Shaw + + * revoke.c (ask_revocation_reason): Allow to select "no reason". + By David Shaw. + + * keyid.c (fingerprint_from_sk): Calculation of an v3 fpr was + plain wrong - nearly the same code in fingerprint_from_pk is correct. + + * build-packet.c (do_secret_key): Added a few comments to the code. + +2001-11-07 Werner Koch <[email protected]> + + * g10.c (main): Print a warning when -r is used w/o encryption. + Suggested by Pascal Scheffers. + 2001-10-23 Werner Koch <[email protected]> * keyedit.c (keyedit_menu): Changed helptext for showpref diff --git a/g10/build-packet.c b/g10/build-packet.c index 1b0351e97..610968bc8 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -340,13 +340,16 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) { int rc = 0; int i, nskey, npkey; - IOBUF a = iobuf_temp(); + IOBUF a = iobuf_temp(); /* build in a self-enlarging buffer */ + /* Write the version number - if none is specified, use 3 */ if( !sk->version ) iobuf_put( a, 3 ); else iobuf_put( a, sk->version ); write_32(a, sk->timestamp ); + + /* v3 needs the expiration time */ if( sk->version < 4 ) { u16 ndays; if( sk->expiredate ) @@ -355,28 +358,46 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) ndays = 0; write_16(a, ndays); } + iobuf_put(a, sk->pubkey_algo ); + + /* get number of secret and public parameters. They are held in + one array first the public ones, then the secret ones */ nskey = pubkey_get_nskey( sk->pubkey_algo ); npkey = pubkey_get_npkey( sk->pubkey_algo ); + + /* If we don't have any public parameters - which is the case if + we don't know the algorithm used - the parameters are stored as + one blob in a faked (opaque) MPI */ if( !npkey ) { write_fake_data( a, sk->skey[0] ); goto leave; } assert( npkey < nskey ); + /* Writing the public parameters is easy */ for(i=0; i < npkey; i++ ) mpi_write(a, sk->skey[i] ); + + /* build the header for protected (encrypted) secret parameters */ if( sk->is_protected ) { if( is_RSA(sk->pubkey_algo) && sk->version < 4 && !sk->protect.s2k.mode ) { + /* the simple rfc1991 (v3) way */ iobuf_put(a, sk->protect.algo ); iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); } else { + /* OpenPGP protection according to rfc2440 */ iobuf_put(a, 0xff ); iobuf_put(a, sk->protect.algo ); if( sk->protect.s2k.mode >= 1000 ) { - iobuf_put(a, 101 ); + /* These modes are not possible in OpenPGP, we use them + to implement our extesnsions, 101 can ve views as a + private/experimental extension (this is not + specified in rfc2440 but the same scheme is used + for all other algorithm identifiers) */ + iobuf_put(a, 101 ); iobuf_put(a, sk->protect.s2k.hash_algo ); iobuf_write(a, "GNU", 3 ); iobuf_put(a, sk->protect.s2k.mode - 1000 ); @@ -389,33 +410,41 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) || sk->protect.s2k.mode == 3 ) iobuf_write(a, sk->protect.s2k.salt, 8 ); if( sk->protect.s2k.mode == 3 ) - iobuf_put(a, sk->protect.s2k.count ); + iobuf_put(a, sk->protect.s2k.count ); + + /* For out special mode 1001 we do not need an IV */ if( sk->protect.s2k.mode != 1001 ) iobuf_write(a, sk->protect.iv, sk->protect.ivlen ); } } else iobuf_put(a, 0 ); + if( sk->protect.s2k.mode == 1001 ) - ; + ; /* GnuPG extension - don't write a secret key at all */ else if( sk->is_protected && sk->version >= 4 ) { + /* The secret key is protected - write it out as it is */ byte *p; assert( mpi_is_opaque( sk->skey[npkey] ) ); p = mpi_get_opaque( sk->skey[npkey], &i ); iobuf_write(a, p, i ); } else { + /* v3 way - same code for protected and non- protected key */ for( ; i < nskey; i++ ) mpi_write(a, sk->skey[i] ); write_16(a, sk->csum ); } leave: + /* Build the header of the packet - which we must do after writing all + the other stuff, so that we know the length of the packet */ write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes, 1 ); + /* And finally write it out the real stream */ if( iobuf_write_temp( out, a ) ) rc = G10ERR_WRITE_FILE; - iobuf_close(a); + iobuf_close(a); /* close the remporary buffer */ return rc; } @@ -180,6 +180,8 @@ enum cmd_and_opt_values { aNull = 0, oThrowKeyid, oForceV3Sigs, oNoForceV3Sigs, + oForceV4Certs, + oNoForceV4Certs, oForceMDC, oS2KMode, oS2KDigest, @@ -311,6 +313,8 @@ static ARGPARSE_OPTS opts[] = { { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") }, { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") }, { oNoForceV3Sigs, "no-force-v3-sigs", 0, N_("do not force v3 signatures") }, + { 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") }, { oDryRun, "dry-run", 0, N_("do not make any changes") }, /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */ @@ -668,6 +672,7 @@ main( int argc, char **argv ) char *preference_list = NULL; int pwfd = -1; int with_fpr = 0; /* make an option out of --fingerprint */ + int any_explicit_recipient = 0; #ifdef USE_SHM_COPROCESSING ulong requested_shm_size=0; #endif @@ -956,6 +961,7 @@ main( int argc, char **argv ) case oRFC1991: opt.rfc1991 = 1; opt.rfc2440 = 0; + opt.force_v4_certs = 0; opt.no_comment = 1; opt.escape_from = 1; break; @@ -998,6 +1004,8 @@ main( int argc, char **argv ) case oThrowKeyid: opt.throw_keyid = 1; break; case oForceV3Sigs: opt.force_v3_sigs = 1; break; case oNoForceV3Sigs: opt.force_v3_sigs = 0; break; + case oForceV4Certs: opt.force_v4_certs = 1; break; + case oNoForceV4Certs: opt.force_v4_certs = 0; break; case oForceMDC: opt.force_mdc = 1; break; case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break; @@ -1010,6 +1018,7 @@ main( int argc, char **argv ) break; case oRecipient: /* store the recipient */ add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); + any_explicit_recipient = 1; break; case oTextmodeShort: opt.textmode = 2; break; case oTextmode: opt.textmode=1; break; @@ -1279,6 +1288,20 @@ main( int argc, char **argv ) log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc)); + switch (cmd) { + case aStore: + case aSym: + case aSign: + case aSignSym: + case aClearsign: + if (!opt.quiet && any_explicit_recipient) + log_info ("WARNING: recipients (-r) given " + "without using public key encryption"); + break; + default: + break; + } + switch( cmd ) { case aStore: /* only store the file */ if( argc > 1 ) diff --git a/g10/keyid.c b/g10/keyid.c index 59f3883c0..1e81545e6 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -457,10 +457,10 @@ fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len ) md = md_open( DIGEST_ALGO_MD5, 0); if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) { - p = buf = mpi_get_buffer( sk->skey[1], &n, NULL ); + p = buf = mpi_get_buffer( sk->skey[0], &n, NULL ); md_write( md, p, n ); m_free(buf); - p = buf = mpi_get_buffer( sk->skey[0], &n, NULL ); + p = buf = mpi_get_buffer( sk->skey[1], &n, NULL ); md_write( md, p, n ); m_free(buf); } diff --git a/g10/options.h b/g10/options.h index 5995d7da6..24012ff10 100644 --- a/g10/options.h +++ b/g10/options.h @@ -57,6 +57,7 @@ struct { int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/ int def_cipher_algo; int force_v3_sigs; + int force_v4_certs; int force_mdc; int def_digest_algo; int def_compress_algo; diff --git a/g10/pkclist.c b/g10/pkclist.c index 9a4e4dd0f..4a4cf633b 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -241,7 +241,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, keyid_from_pk (pk, keyid); for(;;) { /* a string with valid answers */ - const char *ans = _("sSmMqQ"); + const char *ans = _("iImMqQsS"); if( !did_help ) { @@ -268,15 +268,18 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, tty_printf (_(" %d = I trust fully\n"), 4); if (mode) tty_printf (_(" %d = I trust ultimately\n"), 5); - tty_printf (_(" s = please show me more information\n") ); + tty_printf (_(" i = please show me more information\n") ); if( mode ) tty_printf(_(" m = back to the main menu\n")); else - tty_printf(_(" q = quit\n")); + { + tty_printf(_(" s = skip this key\n")); + tty_printf(_(" q = quit\n")); + } tty_printf("\n"); did_help = 1; } - if( strlen(ans) != 6 ) + if( strlen(ans) != 8 ) BUG(); p = cpr_get("edit_ownertrust.value",_("Your decision? ")); trim_spaces(p); @@ -319,6 +322,10 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, { break ; /* back to the menu */ } + else if( !mode && (*p == ans[6] || *p == ans[7] ) ) + { + break; /* skip */ + } else if( !mode && (*p == ans[4] || *p == ans[5] ) ) { quit = 1; @@ -346,7 +353,7 @@ edit_ownertrust (PKT_public_key *pk, int mode ) switch ( do_edit_ownertrust (pk, mode, &trust, no_help ) ) { case -1: /* quit */ - return 0; + return -1; case -2: /* show info */ show_paths(pk, 1); no_help = 1; @@ -355,7 +362,7 @@ edit_ownertrust (PKT_public_key *pk, int mode ) trust &= ~TRUST_FLAG_DISABLED; trust |= get_ownertrust (pk) & TRUST_FLAG_DISABLED; update_ownertrust (pk, trust ); - return 0; + return 1; default: return 0; } diff --git a/g10/revoke.c b/g10/revoke.c index 812722eef..453620c7c 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -240,9 +240,10 @@ gen_revoke( const char *uname ) struct revocation_reason_info * ask_revocation_reason( int key_rev, int cert_rev, int hint ) { - int code; + int code=-1; char *description = NULL; struct revocation_reason_info *reason; + const char *text_0 = _("No reason specified"); const char *text_1 = _("Key has been compromised"); const char *text_2 = _("Key is superseded"); const char *text_3 = _("Key is no longer used"); @@ -254,6 +255,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint ) description = NULL; tty_printf(_("Please select the reason for the revocation:\n")); + tty_printf( " 0 = %s\n", text_0 ); if( key_rev ) tty_printf(" 1 = %s\n", text_1 ); if( key_rev ) @@ -262,29 +264,31 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint ) tty_printf(" 3 = %s\n", text_3 ); if( cert_rev ) tty_printf(" 4 = %s\n", text_4 ); - tty_printf( " 0 = %s\n", _("Cancel") ); + tty_printf( " Q = %s\n", _("Cancel") ); if( hint ) tty_printf(_("(Probably you want to select %d here)\n"), hint ); - for(code = 0; !code;) { + while(code==-1) { int n; char *answer = cpr_get("ask_revocation_reason.code", _("Your decision? ")); trim_spaces( answer ); cpr_kill_prompt(); - if( *answer == 'q' || *answer == 'Q' ) - n = 0; - else if( !isdigit( *answer ) ) - n = -1; - else if( hint && !*answer ) + if( *answer == 'q' || *answer == 'Q') + return NULL; /* cancel */ + if( hint && !*answer ) n = hint; + else if(!isdigit( *answer ) ) + n = -1; else n = atoi(answer); m_free(answer); - if( !n ) - return NULL; /* cancel */ + if( n == 0 ) { + code = 0x00; /* no particular reason */ + code_text = text_0; + } else if( key_rev && n == 1 ) { - code = 0x02; /* key has been compromised */ + code = 0x02; /* key has been compromised */ code_text = text_1; } else if( key_rev && n == 2 ) { diff --git a/g10/sign.c b/g10/sign.c index cd560aeea..f5d2dae11 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -982,15 +982,31 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, || sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x30 || sigclass == 0x28 ); + if (opt.force_v4_certs) + sigversion = 4; + if (sigversion < sk->version) sigversion = sk->version; + /* If you are making a signature on a v4 key using your v3 key, it + doesn't make sense to generate a v3 sig. After all, no v3-only + PGP implementation could understand the v4 key in the first + place. */ + if (sigversion < pk->version) + sigversion = pk->version; + if( !digest_algo ) { switch( sk->pubkey_algo ) { - case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break; + case PUBKEY_ALGO_DSA: + digest_algo = DIGEST_ALGO_SHA1; + break; case PUBKEY_ALGO_RSA_S: - case PUBKEY_ALGO_RSA: digest_algo = DIGEST_ALGO_MD5; break; - default: digest_algo = DIGEST_ALGO_RMD160; break; + case PUBKEY_ALGO_RSA: + digest_algo = sk->version < 4? DIGEST_ALGO_MD5 : DIGEST_ALGO_SHA1; + break; + default: + digest_algo = DIGEST_ALGO_RMD160; + break; } } md = md_open( digest_algo, 0 ); diff --git a/g10/trustdb.c b/g10/trustdb.c index 9c29d1af7..ec80329c6 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -846,12 +846,12 @@ enum_cert_paths_print( void **context, FILE *fp, *********** NEW NEW NEW **************** ****************************************/ -static unsigned int +static int ask_ownertrust (u32 *kid) { PKT_public_key *pk; int rc; - unsigned int ot; + int ot; pk = m_alloc_clear (sizeof *pk); rc = get_pubkey (pk, kid); @@ -862,10 +862,13 @@ ask_ownertrust (u32 *kid) return TRUST_UNKNOWN; } - if (edit_ownertrust (pk, 0)) + ot=edit_ownertrust(pk,0); + if(ot>0) ot = get_ownertrust (pk); - else + else if(ot==0) ot = TRUST_UNDEFINED; + else + ot = -1; /* quit */ free_public_key( pk ); return ot; } @@ -1303,6 +1306,7 @@ static int validate_keys (int interactive) { int rc = 0; + int quit=0; struct key_item *klist = NULL; struct key_item *k; struct key_array *keys = NULL; @@ -1315,6 +1319,7 @@ validate_keys (int interactive) KeyHashTable visited; u32 next_expire; + next_expire = 0xffffffff; /* set next expire to the year 2106 */ visited = new_key_hash_table (); /* Fixme: Instead of always building a UTK list, we could just build it * here when needed */ @@ -1324,7 +1329,6 @@ validate_keys (int interactive) goto leave; } - next_expire = 0xffffffff; /* set next expire to the year 2106 */ /* mark all UTKs as visited and set validity to ultimate */ for (k=utk_list; k; k = k->next) @@ -1377,7 +1381,12 @@ validate_keys (int interactive) { if (interactive && k->ownertrust == TRUST_UNKNOWN) k->ownertrust = ask_ownertrust (k->kid); - if (k->ownertrust == TRUST_UNKNOWN) + if (k->ownertrust == -1) + { + quit=1; + goto leave; + } + else if (k->ownertrust == TRUST_UNKNOWN) ot_unknown++; else if (k->ownertrust == TRUST_UNDEFINED) ot_undefined++; @@ -1448,7 +1457,7 @@ validate_keys (int interactive) release_key_array (keys); release_key_items (klist); release_key_hash_table (visited); - if (!rc) /* mark trustDB as checked */ + if (!rc && !quit) /* mark trustDB as checked */ { if (next_expire == 0xffffffff) tdbio_write_nextcheck (0); |