From cbff0b05e54d7aa022c88e76dddd8d5106cc3536 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 13 Feb 2004 17:06:34 +0000 Subject: [PATCH] * command.c (cmd_setkeydesc): New. (register_commands): Add command SETKEYDESC. (cmd_pksign, cmd_pkdecrypt): Use the key description. (reset_notify): Reset the description. * findkey.c (unprotect): Add arg DESC_TEXT. (agent_key_from_file): Ditto. * pksign.c (agent_pksign): Ditto. * pkdecrypt.c (agent_pkdecrypt): Ditto. Made CIPHERTEXT an unsigned char*. --- NEWS | 7 ++- agent/ChangeLog | 10 ++++ agent/agent.h | 30 +++++++----- agent/command.c | 114 ++++++++++++++++++++++++++++++++++------------ agent/findkey.c | 16 ++++--- agent/pkdecrypt.c | 6 ++- agent/pksign.c | 4 +- 7 files changed, 134 insertions(+), 53 deletions(-) diff --git a/NEWS b/NEWS index 41edd66af..07216f555 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,11 @@ Noteworthy changes in version 1.9.5 Cleaned up the build system to better comply with the coding standards. - * The --import command is now able to autodetect pkcs#12 files and - import secret and private keys from this file format. + * [gpgsm] The --import command is now able to autodetect pkcs#12 + files and import secret and private keys from this file format. + + * [gpgsm] The pinentry will no present a description of the key for + whom the passphrase is requests. Noteworthy changes in version 1.9.4 (2004-01-30) diff --git a/agent/ChangeLog b/agent/ChangeLog index b3c5d73d6..f064bc17c 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,5 +1,15 @@ 2004-02-13 Werner Koch + * command.c (cmd_setkeydesc): New. + (register_commands): Add command SETKEYDESC. + (cmd_pksign, cmd_pkdecrypt): Use the key description. + (reset_notify): Reset the description. + * findkey.c (unprotect): Add arg DESC_TEXT. + (agent_key_from_file): Ditto. + * pksign.c (agent_pksign): Ditto. + * pkdecrypt.c (agent_pkdecrypt): Ditto. Made CIPHERTEXT an + unsigned char*. + * protect-tool.c (main): New options --no-fail-on-exist, --homedir. (store_private_key): Use them here. diff --git a/agent/agent.h b/agent/agent.h index b70a4ae2d..a849e873f 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -132,18 +132,20 @@ void start_command_handler (int, int); /*-- findkey.c --*/ int agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force); -gpg_error_t agent_key_from_file (CTRL ctrl, const unsigned char *grip, +gpg_error_t agent_key_from_file (ctrl_t ctrl, + const char *desc_text, + const unsigned char *grip, unsigned char **shadow_info, int ignore_cache, gcry_sexp_t *result); int agent_key_available (const unsigned char *grip); /*-- query.c --*/ -int agent_askpin (CTRL ctrl, +int agent_askpin (ctrl_t ctrl, const char *desc_text, struct pin_entry_info_s *pininfo); -int agent_get_passphrase (CTRL ctrl, char **retpass, +int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, const char *errtext); -int agent_get_confirmation (CTRL ctrl, const char *desc, const char *ok, +int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, const char *cancel); /*-- cache.c --*/ @@ -154,16 +156,18 @@ void agent_unlock_cache_entry (void **cache_id); /*-- pksign.c --*/ -int agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache); +int agent_pksign (ctrl_t ctrl, const char *desc_text, + FILE *outfp, int ignore_cache); /*-- pkdecrypt.c --*/ -int agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, +int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text, + const unsigned char *ciphertext, size_t ciphertextlen, FILE *outfp); /*-- genkey.c --*/ -int agent_genkey (CTRL ctrl, +int agent_genkey (ctrl_t ctrl, const char *keyparam, size_t keyparmlen, FILE *outfp); -int agent_protect_and_store (CTRL ctrl, gcry_sexp_t s_skey); +int agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey); /*-- protect.c --*/ int agent_protect (const unsigned char *plainkey, const char *passphrase, @@ -181,18 +185,20 @@ int agent_get_shadow_info (const unsigned char *shadowkey, /*-- trustlist.c --*/ int agent_istrusted (const char *fpr); int agent_listtrusted (void *assuan_context); -int agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag); +int agent_marktrusted (ctrl_t ctrl, const char *name, + const char *fpr, int flag); /*-- divert-scd.c --*/ -int divert_pksign (CTRL ctrl, +int divert_pksign (ctrl_t ctrl, const unsigned char *digest, size_t digestlen, int algo, const unsigned char *shadow_info, unsigned char **r_sig); -int divert_pkdecrypt (CTRL ctrl, +int divert_pkdecrypt (ctrl_t ctrl, const unsigned char *cipher, const unsigned char *shadow_info, char **r_buf, size_t *r_len); -int divert_generic_cmd (CTRL ctrl, const char *cmdline, void *assuan_context); +int divert_generic_cmd (ctrl_t ctrl, + const char *cmdline, void *assuan_context); /*-- call-scd.c --*/ diff --git a/agent/command.c b/agent/command.c index aec48e194..2fa182f63 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1,5 +1,5 @@ /* command.c - gpg-agent command handler - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -50,6 +50,8 @@ struct server_local_s { ASSUAN_CONTEXT assuan_ctx; int message_fd; int use_cache_for_signing; + char *keydesc; /* Allocated description fro the next key + operation. */ }; @@ -59,11 +61,14 @@ struct server_local_s { static void reset_notify (ASSUAN_CONTEXT ctx) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); memset (ctrl->keygrip, 0, 20); ctrl->have_keygrip = 0; ctrl->digest.valuelen = 0; + + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; } @@ -78,6 +83,18 @@ has_option (const char *line, const char *name) return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); } +/* Replace all '+' by a blank. */ +static void +plus_to_blank (char *s) +{ + for (; *s; s++) + { + if (*s == '+') + *s = ' '; + } +} + + /* Parse a hex string. Return an Assuan error code or 0 on success and the length of the parsed string in LEN. */ static int @@ -179,7 +196,7 @@ cmd_listtrusted (ASSUAN_CONTEXT ctx, char *line) static int cmd_marktrusted (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc, n, i; char *p; char fpr[41]; @@ -245,7 +262,7 @@ static int cmd_sigkey (ASSUAN_CONTEXT ctx, char *line) { int rc; - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); rc = parse_keygrip (ctx, line, ctrl->keygrip); if (rc) @@ -255,6 +272,50 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line) } +/* SETKEYDESC plus_percent_escaped_string: + + Set a description to be used for the next PKSIGN or PKDECRYPT + operation if this operation requires the entry of a passphrase. If + this command is not used a default text will be used. Note, that + this description implictly selects the label used for the entry + box; if the string contains the string PIN (which in general will + not be translated), "PIN" is used, other wiese the translation of + 'passphrase" is used. The description string should not contain + blanks unless they are percent or '+' escaped. + + The descrition is only valid for the next PKSIGN or PKDECRYPT + operation. +*/ +static int +cmd_setkeydesc (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + char *desc, *p; + + for (p=line; *p == ' '; p++) + ; + desc = p; + p = strchr (desc, ' '); + if (p) + *p = 0; /* We ignore any garbage; we might late use it for other args. */ + + if (!desc || !*desc) + return set_error (Parameter_Error, "no description given"); + + /* Note, that we only need to replace the + characters and should + leave the other escaping in place because the escaped string is + send verbatim to the pinentry which does the unescaping (but not + the + replacing) */ + plus_to_blank (desc); + + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = xtrystrdup (desc); + if (!ctrl->server_local->keydesc) + return map_to_assuan_status (gpg_error_from_errno (errno)); + return 0; +} + + /* SETHASH The client can use this command to tell the server about the data @@ -265,7 +326,7 @@ cmd_sethash (ASSUAN_CONTEXT ctx, char *line) int rc; size_t n; char *p; - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); unsigned char *buf; char *endp; int algo; @@ -307,16 +368,19 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line) { int rc; int ignore_cache = 0; - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); if (opt.ignore_cache_for_signing) ignore_cache = 1; else if (!ctrl->server_local->use_cache_for_signing) ignore_cache = 1; - rc = agent_pksign (ctrl, assuan_get_data_fp (ctx), ignore_cache); + rc = agent_pksign (ctrl, ctrl->server_local->keydesc, + assuan_get_data_fp (ctx), ignore_cache); if (rc) log_error ("command pksign failed: %s\n", gpg_strerror (rc)); + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; return map_to_assuan_status (rc); } @@ -328,7 +392,7 @@ static int cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) { int rc; - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); unsigned char *value; size_t valuelen; @@ -338,10 +402,13 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) if (rc) return rc; - rc = agent_pkdecrypt (ctrl, value, valuelen, assuan_get_data_fp (ctx)); + rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc, + value, valuelen, assuan_get_data_fp (ctx)); xfree (value); if (rc) log_error ("command pkdecrypt failed: %s\n", gpg_strerror (rc)); + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; return map_to_assuan_status (rc); } @@ -363,7 +430,7 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line) static int cmd_genkey (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; unsigned char *value; size_t valuelen; @@ -381,16 +448,6 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line) } -static void -plus_to_blank (char *s) -{ - for (; *s; s++) - { - if (*s == '+') - *s = ' '; - } -} - /* GET_PASSPHRASE [ ] This function is usually used to ask for a passphrase to be used @@ -405,7 +462,7 @@ plus_to_blank (char *s) static int cmd_get_passphrase (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; const char *pw; char *response; @@ -530,15 +587,15 @@ cmd_clear_passphrase (ASSUAN_CONTEXT ctx, char *line) command uses a syntax which helps clients to use the agent with minimum effort. The agent either returns with an error or with a OK. Note, that the length of DESCRIPTION is implicitly limited by - the maximum length of a command. DESCRIPTION should not conmtain - ant spaces, those must be encoded either percent escaped or simply + the maximum length of a command. DESCRIPTION should not contain + any spaces, those must be encoded either percent escaped or simply as '+'. */ static int cmd_get_confirmation (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; char *desc = NULL; char *p; @@ -596,7 +653,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line) static int cmd_passwd (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; unsigned char grip[20]; gcry_sexp_t s_skey = NULL; @@ -607,7 +664,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line) return rc; /* we can't jump to leave because this is already an Assuan error code. */ - rc = agent_key_from_file (ctrl, grip, &shadow_info, 1, &s_skey); + rc = agent_key_from_file (ctrl, NULL, grip, &shadow_info, 1, &s_skey); if (rc) ; else if (!s_skey) @@ -633,7 +690,7 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line) static int cmd_scd (ASSUAN_CONTEXT ctx, char *line) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; rc = divert_generic_cmd (ctrl, line, ctx); @@ -646,7 +703,7 @@ cmd_scd (ASSUAN_CONTEXT ctx, char *line) static int option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value) { - CTRL ctrl = assuan_get_pointer (ctx); + ctrl_t ctrl = assuan_get_pointer (ctx); if (!strcmp (key, "display")) { @@ -715,6 +772,7 @@ register_commands (ASSUAN_CONTEXT ctx) { "HAVEKEY", cmd_havekey }, { "SIGKEY", cmd_sigkey }, { "SETKEY", cmd_sigkey }, + { "SETKEYDESC", cmd_setkeydesc }, { "SETHASH", cmd_sethash }, { "PKSIGN", cmd_pksign }, { "PKDECRYPT", cmd_pkdecrypt }, diff --git a/agent/findkey.c b/agent/findkey.c index f145daef1..14ca38448 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -1,5 +1,5 @@ /* findkey.c - locate the secret key - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -138,9 +138,10 @@ try_unprotect_cb (struct pin_entry_info_s *pi) /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP should be the hex encoded keygrip of that key to be used with the - caching mechanism. */ + caching mechanism. DESC_TEXT may be set to override the default + description used for the pinentry. */ static int -unprotect (CTRL ctrl, +unprotect (CTRL ctrl, const char *desc_text, unsigned char **keybuf, const unsigned char *grip, int ignore_cache) { struct pin_entry_info_s *pi; @@ -184,7 +185,7 @@ unprotect (CTRL ctrl, arg.unprotected_key = NULL; pi->check_cb_arg = &arg; - rc = agent_askpin (ctrl, NULL, pi); + rc = agent_askpin (ctrl, desc_text, pi); if (!rc) { assert (arg.unprotected_key); @@ -203,9 +204,10 @@ unprotect (CTRL ctrl, diverted to a token; SHADOW_INFO will point then to an allocated S-Expression with the shadow_info part from the file. With IGNORE_CACHE passed as true the passphrase is not taken from the - cache.*/ + cache. DESC_TEXT may be set to present a custom description for the + pinentry. */ gpg_error_t -agent_key_from_file (CTRL ctrl, +agent_key_from_file (CTRL ctrl, const char *desc_text, const unsigned char *grip, unsigned char **shadow_info, int ignore_cache, gcry_sexp_t *result) { @@ -286,7 +288,7 @@ agent_key_from_file (CTRL ctrl, case PRIVATE_KEY_CLEAR: break; /* no unprotection needed */ case PRIVATE_KEY_PROTECTED: - rc = unprotect (ctrl, &buf, grip, ignore_cache); + rc = unprotect (ctrl, desc_text, &buf, grip, ignore_cache); if (rc) log_error ("failed to unprotect the secret key: %s\n", gpg_strerror (rc)); diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 72f81778e..eaa2b2254 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -35,7 +35,8 @@ Try to get the key from CTRL and write the decoded stuff back to OUTFP. */ int -agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, +agent_pkdecrypt (CTRL ctrl, const char *desc_text, + const unsigned char *ciphertext, size_t ciphertextlen, FILE *outfp) { gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL; @@ -64,7 +65,8 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, log_printhex ("keygrip:", ctrl->keygrip, 20); log_printhex ("cipher: ", ciphertext, ciphertextlen); } - rc = agent_key_from_file (ctrl, ctrl->keygrip, &shadow_info, 0, &s_skey); + rc = agent_key_from_file (ctrl, desc_text, + ctrl->keygrip, &shadow_info, 0, &s_skey); if (rc) { log_error ("failed to read the secret key\n"); diff --git a/agent/pksign.c b/agent/pksign.c index 34381365e..8bec33c0b 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -70,7 +70,7 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash) /* SIGN whatever information we have accumulated in CTRL and write it back to OUTFP. */ int -agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) +agent_pksign (CTRL ctrl, const char *desc_text, FILE *outfp, int ignore_cache) { gcry_sexp_t s_skey = NULL, s_hash = NULL, s_sig = NULL; unsigned char *shadow_info = NULL; @@ -81,7 +81,7 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) if (!ctrl->have_keygrip) return gpg_error (GPG_ERR_NO_SECKEY); - rc = agent_key_from_file (ctrl, ctrl->keygrip, + rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip, &shadow_info, ignore_cache, &s_skey); if (rc) {