diff --git a/common/ChangeLog b/common/ChangeLog index c056c4c65..b9c48188e 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2009-08-06 Werner Koch + + * status.h (STATUS_INV_SGNR, STATUS_NO_SGNR): New. + * status.c (get_inv_recpsgnr_code): New. + 2009-07-23 David Shaw * srv.c (getsrv): Fix type-punning warning. diff --git a/common/status.c b/common/status.c index 7012edf03..e9f84bfd1 100644 --- a/common/status.c +++ b/common/status.c @@ -36,3 +36,30 @@ get_status_string ( int no ) return statusstr_msgstr + statusstr_msgidx[idx]; } + +const char * +get_inv_recpsgnr_code (gpg_error_t err) +{ + const char *errstr; + + switch (gpg_err_code (err)) + { + case GPG_ERR_NO_PUBKEY: errstr = "1"; break; + case GPG_ERR_AMBIGUOUS_NAME: errstr = "2"; break; + case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break; + case GPG_ERR_CERT_REVOKED: errstr = "4"; break; + case GPG_ERR_CERT_EXPIRED: errstr = "5"; break; + case GPG_ERR_NO_CRL_KNOWN: errstr = "6"; break; + case GPG_ERR_CRL_TOO_OLD: errstr = "7"; break; + case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break; + + case GPG_ERR_UNUSABLE_SECKEY: + case GPG_ERR_NO_SECKEY: errstr = "9"; break; + + case GPG_ERR_NOT_TRUSTED: errstr = "10"; break; + case GPG_ERR_MISSING_CERT: errstr = "11"; break; + default: errstr = "0"; break; + } + + return errstr; +} diff --git a/common/status.h b/common/status.h index 50a11914a..a11f2a38c 100644 --- a/common/status.h +++ b/common/status.h @@ -91,7 +91,9 @@ enum STATUS_USERID_HINT, STATUS_UNEXPECTED, STATUS_INV_RECP, + STATUS_INV_SGNR, STATUS_NO_RECP, + STATUS_NO_SGNR, STATUS_ALREADY_SIGNED, STATUS_KEYEXPIRED, @@ -127,6 +129,7 @@ enum const char *get_status_string (int code); +const char *get_inv_recpsgnr_code (gpg_error_t err); #endif /*GNUPG_COMMON_STATUS_H*/ diff --git a/doc/ChangeLog b/doc/ChangeLog index 17d2c5295..628924651 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2009-08-06 Werner Koch + + * DETAILS: Describe the new INV_SNDR and NO_SNDR.. + 2009-07-31 David Shaw * gpg.texi (OpenPGP Options): Don't mention diff --git a/doc/DETAILS b/doc/DETAILS index cf940c0b3..f4be2b95e 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -361,7 +361,7 @@ more arguments in future versions. KEYEXPIRED The key has expired. expire-timestamp is the expiration time - in seconds sice Epoch. This status line is not very useful + in seconds since Epoch. This status line is not very useful because it will also be emitted for expired subkeys even if this subkey is not used. To check whether a key used to sign a message has expired, the EXPKEYSIG status line is to be @@ -571,7 +571,8 @@ more arguments in future versions. Issued by pipemode. INV_RECP - Issued for each unusable recipient. The reasons codes + INV_SGNR + Issued for each unusable recipient/sender. The reasons codes currently in use are: 0 := "No specific reason given". 1 := "Not Found" @@ -584,13 +585,20 @@ more arguments in future versions. 8 := "Policy mismatch" 9 := "Not a secret key" 10 := "Key not trusted" - 11 := "Missing certifciate" (e.g. intermediate or root cert.) + 11 := "Missing certificate" (e.g. intermediate or root cert.) + + Note that for historical reasons the INV_RECP status is also + used for gpgsm's SIGNER command where it relates to signer's + of course. Newer GnuPG versions are using INV_SGNR; + applications should ignore the INV_RECP during the sender's + command processing once they have seen an INV_SGNR. We use + different code so that we can distinguish them while doing an + encrypt+sign. - Note that this status is also used for gpgsm's SIGNER command - where it relates to signer's of course. NO_RECP - Issued when no recipients are usable. + NO_SGNR + Issued when no recipients/senders are usable. ALREADY_SIGNED Warning: This is experimental and might be removed at any time. diff --git a/g10/ChangeLog b/g10/ChangeLog index 4137f1d58..7e6a6f758 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,9 @@ +2009-08-06 Werner Koch + + * skclist.c (build_sk_list): Print INV_SGNR status line. + * seckey-cert.c (do_check): Return G10ERR_UNU_SECKEY instead of + general error. + 2009-08-05 Werner Koch * card-util.c: Enable readline support also in GnuPG-2. diff --git a/g10/cpr.c b/g10/cpr.c index a20a811ff..1533ac661 100644 --- a/g10/cpr.c +++ b/g10/cpr.c @@ -202,6 +202,12 @@ write_status_text_and_buffer ( int no, const char *string, if (first && string) { fputs (string, statusfp); count += strlen (string); + /* Make sure that there is space after the string. */ + if (*string && string[strlen (string)-1] != ' ') + { + putc (' ', statusfp); + count++; + } } first = 0; } diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 821673541..1398b181b 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -53,7 +53,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode, if( sk->protect.s2k.mode == 1001 ) { log_info(_("secret key parts are not available\n")); - return G10ERR_GENERAL; + return G10ERR_UNU_SECKEY; } if( sk->protect.algo == CIPHER_ALGO_NONE ) BUG(); diff --git a/g10/skclist.c b/g10/skclist.c index d644e71b2..70b375aa3 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -128,6 +128,8 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, if( (rc = get_seckey_byname( sk, NULL, unlock )) ) { free_secret_key( sk ); sk = NULL; log_error("no default secret key: %s\n", g10_errstr(rc) ); + write_status_text (STATUS_INV_SGNR, + get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY)); } else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) ) { @@ -138,6 +140,8 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, log_info(_("key is not flagged as insecure - " "can't use it with the faked RNG!\n")); free_secret_key( sk ); sk = NULL; + write_status_text (STATUS_INV_SGNR, + get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED)); } else { @@ -152,6 +156,7 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, { free_secret_key( sk ); sk = NULL; log_error("invalid default secret key: %s\n", g10_errstr(rc) ); + write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc)); } } else { @@ -176,6 +181,9 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, free_secret_key( sk ); sk = NULL; log_error(_("skipped \"%s\": %s\n"), locusr->d, g10_errstr(rc) ); + write_status_text_and_buffer + (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), + locusr->d, strlen (locusr->d), -1); } else if ( key_present_in_sk_list(sk_list, sk) == 0) { free_secret_key(sk); sk = NULL; @@ -186,6 +194,9 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, free_secret_key( sk ); sk = NULL; log_error(_("skipped \"%s\": %s\n"), locusr->d, g10_errstr(rc) ); + write_status_text_and_buffer + (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), + locusr->d, strlen (locusr->d), -1); } else if( !(rc=openpgp_pk_test_algo2 (sk->pubkey_algo, use)) ) { SK_LIST r; @@ -197,11 +208,19 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, _("this is a PGP generated Elgamal key which" " is not secure for signatures!")); free_secret_key( sk ); sk = NULL; + write_status_text_and_buffer + (STATUS_INV_SGNR, + get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE), + locusr->d, strlen (locusr->d), -1); } else if( random_is_faked() && !is_insecure( sk ) ) { log_info(_("key is not flagged as insecure - " "can't use it with the faked RNG!\n")); free_secret_key( sk ); sk = NULL; + write_status_text_and_buffer + (STATUS_INV_SGNR, + get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED), + locusr->d, strlen (locusr->d), -1); } else { r = xmalloc( sizeof *r ); @@ -214,6 +233,9 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, else { free_secret_key( sk ); sk = NULL; log_error("skipped \"%s\": %s\n", locusr->d, g10_errstr(rc) ); + write_status_text_and_buffer + (STATUS_INV_SGNR, get_inv_recpsgnr_code (rc), + locusr->d, strlen (locusr->d), -1); } } } @@ -221,6 +243,7 @@ build_sk_list( strlist_t locusr, SK_LIST *ret_sk_list, if( !rc && !sk_list ) { log_error("no valid signators\n"); + write_status_text (STATUS_NO_SGNR, "0"); rc = G10ERR_NO_USER_ID; } diff --git a/sm/ChangeLog b/sm/ChangeLog index a88b07919..4ac44576e 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,13 @@ +2009-08-06 Werner Koch + + * sign.c (gpgsm_sign): Print INV_SNDR for a bad default key. + + * server.c (cmd_signer): Remove unneeded case for -1. Send + INV_SGNR. Use new map function. + (cmd_recipient): Use new map function. + * gpgsm.c (do_add_recipient): Use new map function for INV_RECP. + (main): Ditto. Also send INV_SGNR. + 2009-07-30 Werner Koch * call-agent.c (learn_cb): Do not store as ephemeral. diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 93e907658..042e5d389 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -704,17 +704,7 @@ do_add_recipient (ctrl_t ctrl, const char *name, { log_error ("can't encrypt to `%s': %s\n", name, gpg_strerror (rc)); gpgsm_status2 (ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - "0", - name, NULL); + get_inv_recpsgnr_code (rc), name, NULL); } else log_info (_("NOTE: won't be able to encrypt to `%s': %s\n"), @@ -1570,19 +1560,10 @@ main ( int argc, char **argv) { log_error (_("can't sign using `%s': %s\n"), sl->d, gpg_strerror (rc)); + gpgsm_status2 (&ctrl, STATUS_INV_SGNR, + get_inv_recpsgnr_code (rc), sl->d, NULL); gpgsm_status2 (&ctrl, STATUS_INV_RECP, - gpg_err_code (rc) == -1? "1": - gpg_err_code (rc) == GPG_ERR_NO_PUBKEY? "1": - gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME? "2": - gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3": - gpg_err_code (rc) == GPG_ERR_CERT_REVOKED? "4": - gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED? "5": - gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN? "6": - gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD? "7": - gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8": - gpg_err_code (rc) == GPG_ERR_NO_SECKEY? "9": - "0", - sl->d, NULL); + get_inv_recpsgnr_code (rc), sl->d, NULL); } } diff --git a/sm/server.c b/sm/server.c index f6c8af99d..b88dc69e9 100644 --- a/sm/server.c +++ b/sm/server.c @@ -384,20 +384,8 @@ cmd_recipient (assuan_context_t ctx, char *line) &ctrl->server_local->recplist, 0); if (rc) { - gpg_err_code_t r = gpg_err_code (rc); gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - r == GPG_ERR_MISSING_CERT? "11": - "0", - line, NULL); + get_inv_recpsgnr_code (rc), line, NULL); } return rc; @@ -415,10 +403,7 @@ cmd_recipient (assuan_context_t ctx, char *line) has to take care of this. All SIGNER commands are cumulative until a RESET but they are *not* reset by an SIGN command becuase it can be expected that set of signers are used for more than one sign - operation. - - Note that this command returns an INV_RECP status which is a bit - strange, but they are very similar. */ + operation. */ static int cmd_signer (assuan_context_t ctx, char *line) { @@ -429,21 +414,12 @@ cmd_signer (assuan_context_t ctx, char *line) &ctrl->server_local->signerlist, 0); if (rc) { - gpg_err_code_t r = gpg_err_code (rc); - gpgsm_status2 (ctrl, STATUS_INV_RECP, - r == -1? "1": - r == GPG_ERR_NO_PUBKEY? "1": - r == GPG_ERR_AMBIGUOUS_NAME? "2": - r == GPG_ERR_WRONG_KEY_USAGE? "3": - r == GPG_ERR_CERT_REVOKED? "4": - r == GPG_ERR_CERT_EXPIRED? "5": - r == GPG_ERR_NO_CRL_KNOWN? "6": - r == GPG_ERR_CRL_TOO_OLD? "7": - r == GPG_ERR_NO_POLICY_MATCH? "8": - r == GPG_ERR_NO_SECKEY? "9": - r == GPG_ERR_MISSING_CERT? "11": - "0", - line, NULL); + gpgsm_status2 (ctrl, STATUS_INV_SGNR, + get_inv_recpsgnr_code (rc), line, NULL); + /* For compatibiliy reasons we also issue the old code after the + new one. */ + gpgsm_status2 (ctrl, STATUS_INV_RECP, + get_inv_recpsgnr_code (rc), line, NULL); } return rc; } diff --git a/sm/sign.c b/sm/sign.c index 0569052ed..776a5a571 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -372,6 +372,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (!cert) { log_error ("no default signer found\n"); + gpgsm_status2 (ctrl, STATUS_INV_SGNR, + get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY), NULL); rc = gpg_error (GPG_ERR_GENERAL); goto leave; } @@ -382,7 +384,15 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, if (!rc) rc = gpgsm_validate_chain (ctrl, cert, "", NULL, 0, NULL, 0, NULL); if (rc) - goto leave; + { + char *tmpfpr; + + tmpfpr = gpgsm_get_fingerprint_hexstring (cert, 0); + gpgsm_status2 (ctrl, STATUS_INV_SGNR, + get_inv_recpsgnr_code (rc), tmpfpr, NULL); + xfree (tmpfpr); + goto leave; + } /* That one is fine - create signerlist. */ signerlist = xtrycalloc (1, sizeof *signerlist);