mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
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:
parent
585d5c62ee
commit
ef1983d58b
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user