diff --git a/NEWS b/NEWS index 6441452c4..70dd798ae 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,13 @@ Noteworthy changes in version 1.4.10 (unreleased) ------------------------------------------------- + * 2048 bit RSA keys are now generated by default. The default + hash algorithm preferences has changed to prefer SHA-256 over + SHA-1. 2048 bit DSA keys are now generated to use a 256 bit + hash algorithm + + * Support v2 OpenPGP cards. + * The algorithm to compute the SIG_ID status has been changed to match the one from 2.0.10. @@ -8,9 +15,7 @@ Noteworthy changes in version 1.4.10 (unreleased) * Fixed a memory leak which made imports of many keys very slow. - * Support v2 OpenPGP cards. - - * FIXME: Anything else? + * Many smaller bug fixes. Noteworthy changes in version 1.4.9 (2008-03-26) diff --git a/g10/ChangeLog b/g10/ChangeLog index 63d1a6315..2f099afec 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,19 @@ +2009-08-03 Werner Koch + + * card-util.c (generate_card_keys): Ask for off-card keys only if + the card supports it. + (get_info_for_key_operation): Read EXTCAP. + (card_store_subkey): Check for non matching sizes. + + * cardglue.c (agent_scd_writecert, agent_scd_readcert): New stubs. + * misc.c (not_in_gpg1_notice): New. + +2009-07-30 Werner Koch + + * misc.c (md5_digest_warn): New. + (print_digest_algo_note): Divert to new function. + * sig-check.c (do_check): Print MD5 warning. + 2009-07-31 David Shaw * gpg.c (main): --pgp6 includes --disable-mdc. diff --git a/g10/card-util.c b/g10/card-util.c index 8c402a00f..d03de0b46 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -952,8 +952,7 @@ change_cert (const char *args) return -1; } -#warning need to implement this fucntion - rc = -1; /*agent_scd_writecert ("OPENPGP.3", data, n);*/ + rc = agent_scd_writecert ("OPENPGP.3", data, n); if (rc) log_error ("error writing certificate to card: %s\n", gpg_strerror (rc)); xfree (data); @@ -982,8 +981,7 @@ read_cert (const char *args) return -1; } -#warning need to implement this fucntion - rc = -1; /*agent_scd_readcert ("OPENPGP.3", &buffer, &length);*/ + rc = agent_scd_readcert ("OPENPGP.3", &buffer, &length); if (rc) log_error ("error reading certificate from card: %s\n", gpg_strerror (rc)); else @@ -1158,6 +1156,8 @@ get_info_for_key_operation (struct agent_card_info_s *info) rc = agent_scd_getattr ("CHV-STATUS", info); if (!rc) rc = agent_scd_getattr ("DISP-NAME", info); + if (!rc) + rc = agent_scd_getattr ("EXTCAP", info); if (rc) log_error (_("error getting current key info: %s\n"), gpg_strerror (rc)); return rc; @@ -1263,21 +1263,27 @@ generate_card_keys (void) if (get_info_for_key_operation (&info)) return; + if (info.extcap.ki) + { #if GNUPG_MAJOR_VERSION == 1 - { - char *answer=cpr_get("cardedit.genkeys.backup_enc", - _("Make off-card backup of encryption key? (Y/n) ")); + char *answer; - want_backup=answer_is_yes_no_default(answer,1); - cpr_kill_prompt(); - xfree(answer); - } + + answer = cpr_get ("cardedit.genkeys.backup_enc", + _("Make off-card backup of encryption key? (Y/n) ")); + + want_backup=answer_is_yes_no_default(answer,1); + cpr_kill_prompt(); + xfree(answer); #else - want_backup = cpr_get_answer_is_yes - ( "cardedit.genkeys.backup_enc", + want_backup = cpr_get_answer_is_yes + ( "cardedit.genkeys.backup_enc", _("Make off-card backup of encryption key? (Y/n) ")); /*FIXME: we need answer_is_yes_no_default()*/ #endif + } + else + want_backup = 0; if ( (info.fpr1valid && !fpr_is_zero (info.fpr1)) || (info.fpr2valid && !fpr_is_zero (info.fpr2)) @@ -1385,6 +1391,8 @@ card_store_subkey (KBNODE node, int use) size_t n; const char *s; int allow_keyno[3]; + unsigned int nbits; + assert (node->pkt->pkttype == PKT_SECRET_KEY || node->pkt->pkttype == PKT_SECRET_SUBKEY); @@ -1393,10 +1401,18 @@ card_store_subkey (KBNODE node, int use) if (get_info_for_key_operation (&info)) return 0; + if (!info.extcap.ki) + { + tty_printf ("The card does not support the import of keys\n"); + tty_printf ("\n"); + goto leave; + } + show_card_key_info (&info); - if (!is_RSA (sk->pubkey_algo) - || (!info.is_v2 && nbits_from_sk (sk) != 1024) ) + nbits = nbits_from_sk (sk); + + if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) ) { tty_printf ("You may only store a 1024 bit RSA key on the card\n"); tty_printf ("\n"); @@ -1429,8 +1445,17 @@ card_store_subkey (KBNODE node, int use) keyno = *answer? atoi(answer): 0; xfree(answer); if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1]) - break; /* Okay. */ - tty_printf(_("Invalid selection.\n")); + { + if (info.is_v2 && !info.extcap.aac + && info.key_attr[keyno-1].nbits != nbits) + { + tty_printf ("Key does not match the card's capability.\n"); + } + else + break; /* Okay. */ + } + else + tty_printf(_("Invalid selection.\n")); } if (replace_existing_key_p (&info, keyno)) diff --git a/g10/cardglue.c b/g10/cardglue.c index 43f46dcd1..f0041889e 100644 --- a/g10/cardglue.c +++ b/g10/cardglue.c @@ -1527,3 +1527,26 @@ agent_clear_pin_cache (const char *sn) xfree (cacheid); } } + + +int +agent_scd_writecert (const char *certidstr, + const unsigned char *certdata, size_t certdatalen) +{ + /* It does not make sense to implement this rarely used and mainly + interactive command in GPG-1. GPG-2 is better suited for this. */ + not_in_gpg1_notice (); + return gpg_error (GPG_ERR_NOT_SUPPORTED); +} + + +int +agent_scd_readcert (const char *certidstr, + void **r_buf, size_t *r_buflen) +{ + /* It does not make sense to implement this rarely used and mainly + interactive command in GPG-1. GPG-2 is better suited for this. */ + *r_buf = NULL; + not_in_gpg1_notice (); + return gpg_error (GPG_ERR_NOT_SUPPORTED); +} diff --git a/g10/cardglue.h b/g10/cardglue.h index dc114aa69..f55ae6e8b 100644 --- a/g10/cardglue.h +++ b/g10/cardglue.h @@ -230,6 +230,13 @@ int agent_scd_checkpin (const char *serialnobuf); void agent_clear_pin_cache (const char *sn); +/* Dummy functions. */ +int agent_scd_writecert (const char *certidstr, + const unsigned char *certdata, size_t certdatalen); +int agent_scd_readcert (const char *certidstr, + void **r_buf, size_t *r_buflen); + + #endif /*ENABLE_CARD_SUPPORT*/ #endif /*GNUPG_G10_CARDGLUE_H*/ diff --git a/g10/main.h b/g10/main.h index 657a481ba..584c4c7f9 100644 --- a/g10/main.h +++ b/g10/main.h @@ -91,6 +91,10 @@ void idea_cipher_warn( int show ); #define idea_cipher_warn(a) #endif +void md5_digest_warn (int show); + +void not_in_gpg1_notice (void); + struct expando_args { PKT_public_key *pk; diff --git a/g10/misc.c b/g10/misc.c index 8bc144a58..f41e5b75c 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -350,8 +350,7 @@ print_digest_algo_note( int algo ) } } else if(algo==DIGEST_ALGO_MD5) - log_info(_("WARNING: digest algorithm %s is deprecated\n"), - digest_algo_to_string(algo)); + md5_digest_warn (1); } /* Return a string which is used as a kind of process ID */ @@ -464,7 +463,41 @@ idea_cipher_warn(int show) } #endif -static unsigned long get_signature_count(PKT_secret_key *sk) +/* Print a warning if the md5 digest algorithm has been used. This + warning is printed only once unless SHOW is used. */ +void +md5_digest_warn (int show) +{ + static int warned = 0; + + if (!warned || show) + { + log_info (_("WARNING: digest algorithm %s is deprecated\n"), + digest_algo_to_string (DIGEST_ALGO_MD5)); + log_info (_("please see %s for more information\n"), + "http://www.gnupg.org/faq/weak-digest-algos.html"); + warned = 1; + } +} + + +void +not_in_gpg1_notice (void) +{ + static int warned = 0; + + if (!warned) + { + log_info (_("NOTE: This feature is not available in %s\n"), "GnuPG 1.x"); + log_info (_("please see %s for more information\n"), + "http://www.gnupg.org/faq/features-not-in-gnupg-1.html"); + warned = 1; + } +} + + +static unsigned long +get_signature_count(PKT_secret_key *sk) { #ifdef ENABLE_CARD_SUPPORT if(sk && sk->is_protected && sk->protect.s2k.mode==1002) diff --git a/g10/sig-check.c b/g10/sig-check.c index 8107ba23e..ee7955aa2 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -318,6 +318,12 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest, mpi_free(result); } + /* Print the MD5 warning if not yet done. Thus at most we get one + warning during signature checking. Note that while validating + a key we might have already checked MD5 key signatures. */ + if (sig->digest_algo == DIGEST_ALGO_MD5) + md5_digest_warn (0); + if( !rc && sig->flags.unknown_critical ) { log_info(_("assuming bad signature from key %s"