mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02: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 *digest, size_t digestlen, int digestalgo,
|
||||||
unsigned char **r_buf, size_t *r_buflen )
|
unsigned char **r_buf, size_t *r_buflen )
|
||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i, pkalgo;
|
||||||
char *p, line[ASSUAN_LINELENGTH];
|
char *p, line[ASSUAN_LINELENGTH];
|
||||||
membuf_t data;
|
membuf_t data;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -342,6 +342,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
|
|||||||
unsigned char *sigbuf;
|
unsigned char *sigbuf;
|
||||||
size_t sigbuflen;
|
size_t sigbuflen;
|
||||||
struct default_inq_parm_s inq_parm;
|
struct default_inq_parm_s inq_parm;
|
||||||
|
gcry_sexp_t sig;
|
||||||
|
|
||||||
(void)desc;
|
(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_RMD160:hashopt = "--hash=rmd160"; break;
|
||||||
case GCRY_MD_MD5: hashopt = "--hash=md5"; break;
|
case GCRY_MD_MD5: hashopt = "--hash=md5"; break;
|
||||||
case GCRY_MD_SHA256:hashopt = "--hash=sha256"; 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:
|
default:
|
||||||
return gpg_error (GPG_ERR_DIGEST_ALGO);
|
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))
|
if (digestlen*2 + 50 > DIM(line))
|
||||||
return gpg_error (GPG_ERR_GENERAL);
|
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 " );
|
p = stpcpy (line, "SCD SETDATA " );
|
||||||
for (i=0; i < digestlen ; i++, p += 2 )
|
for (i=0; i < digestlen ; i++, p += 2 )
|
||||||
sprintf (p, "%02X", digest[i]);
|
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);
|
sigbuf = get_membuf (&data, &sigbuflen);
|
||||||
|
|
||||||
/* Create an S-expression from it which is formatted like this:
|
switch(pkalgo)
|
||||||
"(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)
|
|
||||||
{
|
{
|
||||||
xfree (sigbuf);
|
case GCRY_PK_RSA:
|
||||||
return 0;
|
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);
|
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));
|
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user