diff options
author | Daniel Kahn Gillmor <[email protected]> | 2019-07-23 14:07:17 +0000 |
---|---|---|
committer | NIIBE Yutaka <[email protected]> | 2019-08-12 01:40:49 +0000 |
commit | 64500e7f6dd63c793734e52e270b1ea23cfd1928 (patch) | |
tree | 9cfeb6e5d38e5be886c3558d6bbb13145960ba48 | |
parent | scd: Handle CCID bwi of time extension. (diff) | |
download | gnupg-64500e7f6dd63c793734e52e270b1ea23cfd1928.tar.gz gnupg-64500e7f6dd63c793734e52e270b1ea23cfd1928.zip |
gpg,gpgsm: Handle pkdecrypt responses with/without NUL terminators.
* g10/call-agent.c (agent_pkdecrypt): accept but do not require
NUL-terminated data from the agent.
* sm/call-agent.c (gpgsm_agent_pkdecrypt): accept but do not require
NUL-terminated data from the agent.
--
Cherry-pick master commit of:
3ba091ab8c93c87741a451f579d63dd500d7621d
GnuPG-bug-id: 4652
Signed-off-by: Daniel Kahn Gillmor <[email protected]>
-rw-r--r-- | g10/call-agent.c | 13 | ||||
-rw-r--r-- | sm/call-agent.c | 12 |
2 files changed, 17 insertions, 8 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index b62bd3307..185715a2a 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -2045,25 +2045,28 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, return err; } - put_membuf (&data, "", 1); /* Make sure it is 0 terminated. */ buf = get_membuf (&data, &len); if (!buf) return gpg_error_from_syserror (); - log_assert (len); /* (we forced Nul termination.) */ - if (*buf != '(') + if (len == 0 || *buf != '(') { xfree (buf); return gpg_error (GPG_ERR_INV_SEXP); } - if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */ + if (len < 12 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)" */ { xfree (buf); return gpg_error (GPG_ERR_INV_SEXP); } - len -= 10; /* Count only the data of the second part. */ + while (buf[len-1] == 0) + len--; + if (buf[len-1] != ')') + return gpg_error (GPG_ERR_INV_SEXP); + len--; /* Drop the final close-paren. */ p = buf + 8; /* Skip leading parenthesis and the value tag. */ + len -= 8; /* Count only the data of the second part. */ n = strtoul (p, &endp, 10); if (!n || *endp != ':') diff --git a/sm/call-agent.c b/sm/call-agent.c index 20d879fa4..2ea309b24 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -445,7 +445,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, { int rc; char line[ASSUAN_LINELENGTH]; - membuf_t data; + membuf_t data; struct cipher_parm_s cipher_parm; size_t n, len; char *p, *buf, *endp; @@ -496,7 +496,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, return rc; } - put_membuf (&data, "", 1); /* Make sure it is 0 terminated. */ + put_membuf (&data, "", 1); /* Make sure it is 0 terminated so we can invoke strtoul safely. */ buf = get_membuf (&data, &len); if (!buf) return gpg_error (GPG_ERR_ENOMEM); @@ -506,8 +506,14 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, { if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */ return gpg_error (GPG_ERR_INV_SEXP); - len -= 11; /* Count only the data of the second part. */ + /* Trim any spurious trailing Nuls: */ + while (buf[len-1] == 0) + len--; + if (buf[len-1] != ')') + return gpg_error (GPG_ERR_INV_SEXP); + len--; /* Drop the final close-paren: */ p = buf + 8; /* Skip leading parenthesis and the value tag. */ + len -= 8; /* Count only the data of the second part. */ } else { |