mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-21 19:48:05 +01:00
sm: Support generation of card-based ECDSA CSR.
* sm/call-agent.c (gpgsm_scd_pksign): Identify type of signing key and format resulting S-expression accordingly. -- Current GpgSM implementation assumes card-based keys are RSA keys. This patch introduces support for ECDSA keys. GnuPG-bug-id: 4092 Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org> (cherry picked from commit 74e9b579ca273fc07be090bb5fb7800a97b1b452) - Removed already applied changes from the original commit. - Allow for SHA384 and SHA512 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
4d5126349d
commit
6f276fc17b
@ -334,7 +334,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
||||
unsigned char *digest, size_t digestlen, int digestalgo,
|
||||
unsigned char **r_buf, size_t *r_buflen )
|
||||
{
|
||||
int rc, i;
|
||||
int rc, i, pkalgo;
|
||||
char *p, line[ASSUAN_LINELENGTH];
|
||||
membuf_t data;
|
||||
size_t len;
|
||||
@ -342,6 +342,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
||||
unsigned char *sigbuf;
|
||||
size_t sigbuflen;
|
||||
struct default_inq_parm_s inq_parm;
|
||||
gcry_sexp_t sig;
|
||||
|
||||
(void)desc;
|
||||
|
||||
@ -353,6 +354,8 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
||||
case GCRY_MD_RMD160:hashopt = "--hash=rmd160"; break;
|
||||
case GCRY_MD_MD5: hashopt = "--hash=md5"; break;
|
||||
case GCRY_MD_SHA256:hashopt = "--hash=sha256"; break;
|
||||
case GCRY_MD_SHA384:hashopt = "--hash=sha384"; break;
|
||||
case GCRY_MD_SHA512:hashopt = "--hash=sha512"; break;
|
||||
default:
|
||||
return gpg_error (GPG_ERR_DIGEST_ALGO);
|
||||
}
|
||||
@ -366,6 +369,23 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
||||
if (digestlen*2 + 50 > DIM(line))
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
|
||||
/* Get the key type from the scdaemon. */
|
||||
snprintf (line, DIM(line), "SCD READKEY %s", keyid);
|
||||
init_membuf (&data, 1024);
|
||||
rc = assuan_transact (agent_ctx, line,
|
||||
put_membuf_cb, &data, NULL, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
{
|
||||
xfree (get_membuf (&data, &len));
|
||||
return rc;
|
||||
}
|
||||
|
||||
p = get_membuf (&data, &len);
|
||||
pkalgo = get_pk_algo_from_canon_sexp (p, len);
|
||||
xfree (p);
|
||||
if (!pkalgo)
|
||||
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
||||
|
||||
p = stpcpy (line, "SCD SETDATA " );
|
||||
for (i=0; i < digestlen ; i++, p += 2 )
|
||||
sprintf (p, "%02X", digest[i]);
|
||||
@ -386,24 +406,31 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
||||
}
|
||||
sigbuf = get_membuf (&data, &sigbuflen);
|
||||
|
||||
/* Create an S-expression from it which is formatted like this:
|
||||
"(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" Fixme: If a card ever
|
||||
creates non-RSA keys we need to change things. */
|
||||
*r_buflen = 21 + 11 + sigbuflen + 4;
|
||||
p = xtrymalloc (*r_buflen);
|
||||
*r_buf = (unsigned char*)p;
|
||||
if (!p)
|
||||
switch(pkalgo)
|
||||
{
|
||||
xfree (sigbuf);
|
||||
return 0;
|
||||
case GCRY_PK_RSA:
|
||||
rc = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s%b)))",
|
||||
sigbuflen, sigbuf);
|
||||
break;
|
||||
|
||||
case GCRY_PK_ECC:
|
||||
rc = gcry_sexp_build (&sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))",
|
||||
sigbuflen/2, sigbuf,
|
||||
sigbuflen/2, sigbuf + sigbuflen/2);
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
|
||||
break;
|
||||
}
|
||||
p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
|
||||
sprintf (p, "%u:", (unsigned int)sigbuflen);
|
||||
p += strlen (p);
|
||||
memcpy (p, sigbuf, sigbuflen);
|
||||
p += sigbuflen;
|
||||
strcpy (p, ")))");
|
||||
xfree (sigbuf);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = make_canon_sexp (sig, r_buf, r_buflen);
|
||||
gcry_sexp_release (sig);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user