agent: pksign result conversion to sexp to upper layer.

* agent/agent.h (divert_pksign): Add R_SIGLEN argument.
* agent/divert-scd.c (divert_pksign): Return length at R_SIGLEN.
* agent/call-scd.c (agent_card_pksign): Move composition of
S-expression to...
* agent/pksign.c (agent_pksign_do): ... here.
--

Composing S-expression would be better to be done by SCDaemon.
This commit is contained in:
NIIBE Yutaka 2013-02-28 11:17:47 +09:00
parent 585d5c62ee
commit ef1983d58b
4 changed files with 97 additions and 35 deletions

View File

@ -405,7 +405,8 @@ void agent_reload_trustlist (void);
/*-- divert-scd.c --*/
int divert_pksign (ctrl_t ctrl,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig);
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen);
int divert_pkdecrypt (ctrl_t ctrl,
const unsigned char *cipher,
const unsigned char *shadow_info,

View File

@ -825,10 +825,6 @@ agent_card_pksign (ctrl_t ctrl,
char *p, line[ASSUAN_LINELENGTH];
membuf_t data;
struct inq_needpin_s inqparm;
size_t len;
unsigned char *sigbuf;
size_t sigbuflen;
int prepend_nul;
*r_buf = NULL;
rc = start_scd (ctrl);
@ -868,32 +864,13 @@ agent_card_pksign (ctrl_t ctrl,
if (rc)
{
size_t len;
xfree (get_membuf (&data, &len));
return unlock_scd (ctrl, rc);
}
sigbuf = get_membuf (&data, &sigbuflen);
/* Create an S-expression from it which is formatted like this:
"(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))". We better make sure
that this won't be interpreted as a negative number. */
prepend_nul = (sigbuflen && (*sigbuf & 0x80));
*r_buflen = 21 + 11 + prepend_nul + sigbuflen + 4;
p = xtrymalloc (*r_buflen);
*r_buf = (unsigned char*)p;
if (!p)
return unlock_scd (ctrl, out_of_core ());
p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
sprintf (p, "%u:", (unsigned int)sigbuflen + prepend_nul);
p += strlen (p);
if (prepend_nul)
*p++ = 0;
memcpy (p, sigbuf, sigbuflen);
p += sigbuflen;
strcpy (p, ")))");
xfree (sigbuf);
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
*r_buf = get_membuf (&data, r_buflen);
return unlock_scd (ctrl, 0);
}

View File

@ -335,7 +335,8 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
int
divert_pksign (ctrl_t ctrl,
const unsigned char *digest, size_t digestlen, int algo,
const unsigned char *shadow_info, unsigned char **r_sig)
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen)
{
int rc;
char *kid;
@ -369,7 +370,10 @@ divert_pksign (ctrl_t ctrl,
}
if (!rc)
*r_sig = sigval;
{
*r_sig = sigval;
*r_siglen = siglen;
}
xfree (kid);

View File

@ -278,24 +278,104 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (!s_skey)
{
/* Divert operation to the smartcard */
gcry_sexp_t s_pkey, l;
const char *name;
size_t len;
unsigned char *buf = NULL;
size_t len = 0;
int is_RSA = 0;
int is_ECDSA = 0;
/* Check keytype by public key */
rc = agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey);
if (rc)
{
log_error ("failed to read the public key\n");
goto leave;
}
l = gcry_sexp_cadr (s_pkey);
name = gcry_sexp_nth_data (l, 0, &len);
if (len == 3 && !memcmp (name, "rsa", 3))
is_RSA = 1;
else if (len == 5 && !memcmp (name, "ecdsa", 5))
is_ECDSA = 1;
gcry_sexp_release (l);
gcry_sexp_release (s_pkey);
rc = divert_pksign (ctrl,
ctrl->digest.value,
ctrl->digest.valuelen,
ctrl->digest.algo,
shadow_info, &buf);
shadow_info, &buf, &len);
if (rc)
{
log_error ("smartcard signing failed: %s\n", gpg_strerror (rc));
goto leave;
}
len = gcry_sexp_canon_len (buf, 0, NULL, NULL);
assert (len);
rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len);
if (is_RSA)
{
if (*buf & 0x80)
{
len++;
buf = xtryrealloc (buf, len);
if (!buf)
goto leave;
memmove (buf + 1, buf, len - 1);
*buf = 0;
}
rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%b)))", len, buf);
}
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;
r_buflen = s_buflen = len/2;
if (*buf & 0x80)
{
r_buflen++;
r_buf_allocated = xtrymalloc (r_buflen);
if (!r_buf_allocated)
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)
{
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;
rc = 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
rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
xfree (buf);
if (rc)
{