1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-20 14:37:08 +01:00

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.

GnuPG-bug-id: 4652
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
This commit is contained in:
Daniel Kahn Gillmor 2019-07-23 10:07:17 -04:00 committed by NIIBE Yutaka
parent fd9e6ae22e
commit 3ba091ab8c
2 changed files with 17 additions and 8 deletions

View File

@ -2323,25 +2323,28 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
return err; return err;
} }
put_membuf (&data, "", 1); /* Make sure it is 0 terminated. */
buf = get_membuf (&data, &len); buf = get_membuf (&data, &len);
if (!buf) if (!buf)
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
log_assert (len); /* (we forced Nul termination.) */
if (*buf != '(') if (len == 0 || *buf != '(')
{ {
xfree (buf); xfree (buf);
return gpg_error (GPG_ERR_INV_SEXP); 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); xfree (buf);
return gpg_error (GPG_ERR_INV_SEXP); 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. */ 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); n = strtoul (p, &endp, 10);
if (!n || *endp != ':') if (!n || *endp != ':')

View File

@ -528,7 +528,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
return rc; 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); buf = get_membuf (&data, &len);
if (!buf) if (!buf)
return gpg_error (GPG_ERR_ENOMEM); return gpg_error (GPG_ERR_ENOMEM);
@ -538,8 +538,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" */ if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
return gpg_error (GPG_ERR_INV_SEXP); 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. */ p = buf + 8; /* Skip leading parenthesis and the value tag. */
len -= 8; /* Count only the data of the second part. */
} }
else else
{ {