diff options
-rw-r--r-- | agent/agent.h | 3 | ||||
-rw-r--r-- | agent/findkey.c | 2 | ||||
-rw-r--r-- | agent/protect-tool.c | 17 | ||||
-rw-r--r-- | agent/sexp-secret.c | 24 |
4 files changed, 27 insertions, 19 deletions
diff --git a/agent/agent.h b/agent/agent.h index c713944d8..1cbc432af 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -640,8 +640,7 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data, gcry_sexp_t *r_curve, gcry_sexp_t *r_flags); /*-- sexp-secret.c --*/ -size_t fixup_when_ecc_private_key (unsigned char *buf, size_t buflen); - +gpg_error_t fixup_when_ecc_private_key (unsigned char *buf, size_t *buflen_p); gpg_error_t sexp_sscan_private_key (gcry_sexp_t *result, size_t *r_erroff, unsigned char *buf); diff --git a/agent/findkey.c b/agent/findkey.c index be5e1ea95..0fe7b4621 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -968,7 +968,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce, { gpg_error_t err; unsigned char *buf; - size_t len, buflen, erroff; + size_t len, erroff; gcry_sexp_t s_skey; nvc_t keymeta = NULL; char *desc_text_buffer = NULL; /* Used in case we extend DESC_TEXT. */ diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 178a20849..a95f418e6 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -372,7 +372,7 @@ read_and_protect (const char *fname) static void read_and_unprotect (ctrl_t ctrl, const char *fname) { - int rc; + gpg_error_t err; unsigned char *key; unsigned char *result; size_t resultlen; @@ -383,15 +383,15 @@ read_and_unprotect (ctrl_t ctrl, const char *fname) if (!key) return; - rc = agent_unprotect (ctrl, key, (pw=get_passphrase (1)), - protected_at, &result, &resultlen); + err = agent_unprotect (ctrl, key, (pw=get_passphrase (1)), + protected_at, &result, &resultlen); release_passphrase (pw); xfree (key); - if (rc) + if (err) { if (opt_status_msg) log_info ("[PROTECT-TOOL:] bad-passphrase\n"); - log_error ("unprotecting the key failed: %s\n", gpg_strerror (rc)); + log_error ("unprotecting the key failed: %s\n", gpg_strerror (err)); return; } if (opt.verbose) @@ -404,7 +404,12 @@ read_and_unprotect (ctrl_t ctrl, const char *fname) log_info ("key protection done at [unknown]\n"); } - resultlen = fixup_when_ecc_private_key (result, resultlen); + err = fixup_when_ecc_private_key (result, &resultlen); + if (err) + { + log_error ("malformed key: %s\n", gpg_strerror (err)); + return; + } if (opt_armor) { char *p = make_advanced (result, resultlen); diff --git a/agent/sexp-secret.c b/agent/sexp-secret.c index 9ed9cd402..bf6bacaaf 100644 --- a/agent/sexp-secret.c +++ b/agent/sexp-secret.c @@ -22,13 +22,15 @@ #include "../common/sexp-parse.h" /* - * Fixup private key part in the cannonical SEXP. + * When it's for ECC, fixup private key part in the cannonical SEXP + * representation in BUF. */ -size_t -fixup_when_ecc_private_key (unsigned char *buf, size_t buflen) +gpg_error_t +fixup_when_ecc_private_key (unsigned char *buf, size_t *buflen_p) { const unsigned char *s; size_t n; + size_t buflen = *buflen_p; s = buf; if (*s != '(') @@ -44,7 +46,7 @@ fixup_when_ecc_private_key (unsigned char *buf, size_t buflen) s++; n = snext (&s); if (!smatch (&s, n, "ecc")) - return buflen; + return 0; /* It's ECC */ while (*s == '(') @@ -79,6 +81,7 @@ fixup_when_ecc_private_key (unsigned char *buf, size_t buflen) memset (s0+numsize+buflen - (s - buf), 0, (n0 - numsize) + 1); buflen -= (n0 - numsize); s = s0+numsize+n; + *buflen_p = buflen; } else s += n; @@ -99,7 +102,7 @@ fixup_when_ecc_private_key (unsigned char *buf, size_t buflen) return gpg_error (GPG_ERR_INV_SEXP); s++; - return buflen; + return 0; } gpg_error_t @@ -107,12 +110,13 @@ sexp_sscan_private_key (gcry_sexp_t *result, size_t *r_erroff, unsigned char *buf) { gpg_error_t err; - size_t buflen, buflen1; + size_t buflen, buflen0; - buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL); - buflen1 = fixup_when_ecc_private_key (buf, buflen); - err = gcry_sexp_sscan (result, r_erroff, (char*)buf, buflen1); - wipememory (buf, buflen); + buflen = buflen0 = gcry_sexp_canon_len (buf, 0, NULL, NULL); + err = fixup_when_ecc_private_key (buf, &buflen); + if (!err) + err = gcry_sexp_sscan (result, r_erroff, (char*)buf, buflen0); + wipememory (buf, buflen0); return err; } |