diff --git a/TODO b/TODO index f1355c03c..12fd998aa 100644 --- a/TODO +++ b/TODO @@ -31,9 +31,10 @@ might want to have an agent context for each service request ** Don't hardcode the use of RSA. * sm/gpgsm.c -** Support --output +** Support --output for all commands ** mark all unimplemented commands and options. ** Print a hint when MD2 is the cause for a problem. +** Implement --default-key * sm/keydb.c ** Check file permissions diff --git a/agent/ChangeLog b/agent/ChangeLog index 0e165e31b..263259f6a 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,12 @@ +2004-01-16 Werner Koch + + * findkey.c (agent_key_from_file): Now return an error code so + that we have more detailed error messages in the upper layers. + This fixes the handling pinentry's cancel button. + * pksign.c (agent_pksign): Changed accordingly. + * pkdecrypt.c (agent_pkdecrypt): Ditto. + * command.c (cmd_passwd): Ditto. + 2003-12-16 Werner Koch * gpg-agent.c (main): Set the prefixes for assuan logging. diff --git a/agent/agent.h b/agent/agent.h index eb4f4e32d..95b0ba4cd 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -130,9 +130,9 @@ 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); -gcry_sexp_t agent_key_from_file (CTRL ctrl, const unsigned char *grip, +gpg_error_t agent_key_from_file (CTRL ctrl, const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache); + int ignore_cache, gcry_sexp_t *result); int agent_key_available (const unsigned char *grip); /*-- query.c --*/ diff --git a/agent/command.c b/agent/command.c index a3e1c514a..0406ea439 100644 --- a/agent/command.c +++ b/agent/command.c @@ -606,9 +606,9 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line) return rc; /* we can't jump to leave because this is already an Assuan error code. */ - s_skey = agent_key_from_file (ctrl, grip, &shadow_info, 1); - if (!s_skey && !shadow_info) - rc = gpg_error (GPG_ERR_NO_SECKEY); + rc = agent_key_from_file (ctrl, grip, &shadow_info, 1, &s_skey); + if (rc) + ; else if (!s_skey) { log_error ("changing a smartcard PIN is not yet supported\n"); diff --git a/agent/findkey.c b/agent/findkey.c index db36cb1b9..a9566a2c7 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -198,16 +198,16 @@ unprotect (CTRL ctrl, -/* Return the secret key as an S-Exp after locating it using the grip. - Returns NULL if key is not available or the operation should be - diverted to a token. In the latter case shadow_info will point 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.*/ -gcry_sexp_t +/* Return the secret key as an S-Exp in RESULT after locating it using + the grip. Returns NULL in RESULT if the operation should be + 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.*/ +gpg_error_t agent_key_from_file (CTRL ctrl, const unsigned char *grip, unsigned char **shadow_info, - int ignore_cache) + int ignore_cache, gcry_sexp_t *result) { int i, rc; char *fname; @@ -217,7 +217,9 @@ agent_key_from_file (CTRL ctrl, size_t len, buflen, erroff; gcry_sexp_t s_skey; char hexgrip[40+4+1]; + int got_shadow_info = 0; + *result = NULL; if (shadow_info) *shadow_info = NULL; @@ -229,28 +231,31 @@ agent_key_from_file (CTRL ctrl, fp = fopen (fname, "rb"); if (!fp) { + rc = gpg_error_from_errno (errno); log_error ("can't open `%s': %s\n", fname, strerror (errno)); xfree (fname); - return NULL; + return rc; } if (fstat (fileno(fp), &st)) { + rc = gpg_error_from_errno (errno); log_error ("can't stat `%s': %s\n", fname, strerror (errno)); xfree (fname); fclose (fp); - return NULL; + return rc; } buflen = st.st_size; buf = xmalloc (buflen+1); if (fread (buf, buflen, 1, fp) != 1) { + rc = gpg_error_from_errno (errno); log_error ("error reading `%s': %s\n", fname, strerror (errno)); xfree (fname); fclose (fp); xfree (buf); - return NULL; + return rc; } rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); @@ -261,15 +266,16 @@ agent_key_from_file (CTRL ctrl, { log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (rc)); - return NULL; + return rc; } len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); assert (len); buf = xtrymalloc (len); if (!buf) { + rc = out_of_core (); gcry_sexp_release (s_skey); - return NULL; + return rc; } len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, buf, len); assert (len); @@ -303,26 +309,27 @@ agent_key_from_file (CTRL ctrl, { memcpy (*shadow_info, s, n); rc = 0; + got_shadow_info = 1; } } if (rc) log_error ("get_shadow_info failed: %s\n", gpg_strerror (rc)); } - rc = -1; /* ugly interface: we return an error but keep a value - in shadow_info. */ + else + rc = gpg_error (GPG_ERR_UNUSABLE_SECKEY); break; default: log_error ("invalid private key format\n"); rc = gpg_error (GPG_ERR_BAD_SECKEY); break; } - if (rc) + if (rc || got_shadow_info) { xfree (buf); - return NULL; + return rc; } - /* arggg FIXME: does scan support secure memory? */ + /* Arggg FIXME: does scan support secure memory? */ rc = gcry_sexp_sscan (&s_skey, &erroff, buf, gcry_sexp_canon_len (buf, 0, NULL, NULL)); xfree (buf); @@ -330,10 +337,11 @@ agent_key_from_file (CTRL ctrl, { log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (rc)); - return NULL; + return rc; } - return s_skey; + *result = s_skey; + return 0; } /* Return the secret key as an S-Exp after locating it using the grip. diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index d17c688a0..cc3a2f33f 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -64,11 +64,10 @@ agent_pkdecrypt (CTRL ctrl, const char *ciphertext, size_t ciphertextlen, log_printhex ("keygrip:", ctrl->keygrip, 20); log_printhex ("cipher: ", ciphertext, ciphertextlen); } - s_skey = agent_key_from_file (ctrl, ctrl->keygrip, &shadow_info, 0); - if (!s_skey && !shadow_info) + rc = agent_key_from_file (ctrl, ctrl->keygrip, &shadow_info, 0, &s_skey); + if (rc) { log_error ("failed to read the secret key\n"); - rc = gpg_error (GPG_ERR_NO_SECKEY); goto leave; } diff --git a/agent/pksign.c b/agent/pksign.c index d5fe17bb7..34381365e 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -81,12 +81,11 @@ agent_pksign (CTRL ctrl, FILE *outfp, int ignore_cache) if (!ctrl->have_keygrip) return gpg_error (GPG_ERR_NO_SECKEY); - s_skey = agent_key_from_file (ctrl, - ctrl->keygrip, &shadow_info, ignore_cache); - if (!s_skey && !shadow_info) + rc = agent_key_from_file (ctrl, ctrl->keygrip, + &shadow_info, ignore_cache, &s_skey); + if (rc) { log_error ("failed to read the secret key\n"); - rc = gpg_error (GPG_ERR_NO_SECKEY); goto leave; }