aboutsummaryrefslogtreecommitdiffstats
path: root/agent/pksign.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2019-02-27 01:37:26 +0000
committerNIIBE Yutaka <[email protected]>2019-02-27 01:37:26 +0000
commit0173b249cfb7f02f94911ec759630d81f312e0bd (patch)
tree7dd8533ed700a516e90f6cf13814c28651892846 /agent/pksign.c
parentscd: Simplify the app_readkey parameters. (diff)
downloadgnupg-0173b249cfb7f02f94911ec759630d81f312e0bd.tar.gz
gnupg-0173b249cfb7f02f94911ec759630d81f312e0bd.zip
agent: PKSIGN should return signature in same format for card.
* agent/pksign.c (agent_pksign_do): -- It's best to keep same data format by libgcrypt. For card (due to historical reasons), gpg-agent or scdaemon used to prefix 0x00 when it starts 0x80, so that it can be parsed signed MPI as well as unsigned MPI. It used to do nothing for preceding zeros. Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to 'agent/pksign.c')
-rw-r--r--agent/pksign.c82
1 files changed, 36 insertions, 46 deletions
diff --git a/agent/pksign.c b/agent/pksign.c
index f54af0817..828e63f58 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -367,20 +367,29 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (is_RSA)
{
+ unsigned char *p = buf;
+
check_signature = 1;
- if (*buf & 0x80)
+
+ /*
+ * Smartcard returns fixed-size data, which is good for
+ * PKCS1. If variable-size unsigned MPI is needed, remove
+ * zeros.
+ */
+ if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1
+ || ctrl->digest.raw_value)
{
- len++;
- buf = xtryrealloc (buf, len);
- if (!buf)
- goto leave;
+ int i;
- memmove (buf + 1, buf, len - 1);
- *buf = 0;
+ for (i = 0; i < len - 1; i++)
+ if (p[i])
+ break;
+ p += i;
+ len -= i;
}
err = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))",
- (int)len, buf);
+ (int)len, p);
}
else if (is_EdDSA)
{
@@ -389,53 +398,34 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
}
else if (is_ECDSA)
{
- unsigned char *r_buf_allocated = NULL;
- unsigned char *s_buf_allocated = NULL;
unsigned char *r_buf, *s_buf;
int r_buflen, s_buflen;
+ int i;
r_buflen = s_buflen = len/2;
- if (*buf & 0x80)
- {
- r_buflen++;
- r_buf_allocated = xtrymalloc (r_buflen);
- if (!r_buf_allocated)
- {
- err = gpg_error_from_syserror ();
- goto leave;
- }
-
- r_buf = r_buf_allocated;
- memcpy (r_buf + 1, buf, len/2);
- *r_buf = 0;
- }
- else
- r_buf = buf;
-
- if (*(buf + len/2) & 0x80)
- {
- s_buflen++;
- s_buf_allocated = xtrymalloc (s_buflen);
- if (!s_buf_allocated)
- {
- err = gpg_error_from_syserror ();
- xfree (r_buf_allocated);
- goto leave;
- }
-
- s_buf = s_buf_allocated;
- memcpy (s_buf + 1, buf + len/2, len/2);
- *s_buf = 0;
- }
- else
- s_buf = buf + len/2;
+ /*
+ * Smartcard returns fixed-size data. For ECDSA signature,
+ * variable-size unsigned MPI is assumed, thus, remove
+ * zeros.
+ */
+ r_buf = buf;
+ for (i = 0; i < r_buflen - 1; i++)
+ if (r_buf[i])
+ break;
+ r_buf += i;
+ r_buflen -= i;
+
+ s_buf = buf + len/2;
+ for (i = 0; i < s_buflen - 1; i++)
+ if (s_buf[i])
+ break;
+ s_buf += i;
+ s_buflen -= i;
err = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))",
r_buflen, r_buf,
s_buflen, s_buf);
- xfree (r_buf_allocated);
- xfree (s_buf_allocated);
}
else
err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);