1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

sm: Support creation of EdDSA certificates.

* sm/misc.c (transform_sigval): Support EdDSA.
* sm/certreqgen.c (create_request): Support EdDSA cert creation.
* sm/certcheck.c (gpgsm_check_cert_sig): Map some ECC algo OIDs to
hash algos.
* sm/call-agent.c (struct sethash_inq_parm_s): New.
(sethash_inq_cb): New.
(gpgsm_agent_pksign): Add mode to pass plain data for EdDSA.
--

Tested using a parameter file

    Key-Type: EdDSA
    Key-Length: 1024
    Key-Grip: 09D9AE3D494F7888C93BE5106AD8A734A87617F0
    Key-Usage: sign
    Serial: random
    Name-DN: CN=dummy test ed25519

where the keygrip is from a gpg generated Ed25519 key.  ECDSA was
tested using

    Key-Type: ECDSA
    Key-Length: 1024
    Key-Grip: 8E06A180EFFE4C65B812150CAF19BF30C0689A4C
    Key-Usage: sign
    Serial: random
    Name-DN: CN=dummy test nistp256

and RSA using

    Key-Type: RSA
    Key-Length: 2048
    Key-Grip: C6A6390E9388CDBAD71EAEA698233FE5E04F001E
    Key-Usage: sign
    Serial: random
    Name-DN: CN=dummy test rsa

The command used in all cases is

  gpgsm -v --gen-key --batch  a.parm >a.crt
  gpgsm -v --import <a.crt

More support, in particular in the user interface, is required and
will follow soon.

GnuPG-bug-id: 4888
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-05-18 19:32:30 +02:00
parent b18fb0264a
commit 6dc3846d78
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 184 additions and 64 deletions

View file

@ -67,6 +67,7 @@
#include "keydb.h"
#include "../common/i18n.h"
#include "../common/membuf.h"
enum para_name
@ -835,6 +836,8 @@ create_request (ctrl_t ctrl,
ksba_isotime_t atime;
int certmode = 0;
int mdalgo;
membuf_t tbsbuffer;
membuf_t *tbsmb = NULL;
err = ksba_certreq_new (&cr);
if (err)
@ -842,21 +845,31 @@ create_request (ctrl_t ctrl,
len = gcry_sexp_canon_len (public, 0, NULL, NULL);
if (get_pk_algo_from_canon_sexp (public, len) == GCRY_PK_EDDSA)
mdalgo = GCRY_MD_SHA512;
else if ((string = get_parameter_value (para, pHASHALGO, 0)))
mdalgo = gcry_md_map_name (string);
else
mdalgo = GCRY_MD_SHA256;
rc = gcry_md_open (&md, mdalgo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave;
mdalgo = GCRY_MD_SHA512;
md = NULL; /* We sign the data and not a hash. */
init_membuf (&tbsbuffer, 2048);
tbsmb = &tbsbuffer;
ksba_certreq_set_hash_function
(cr, (void (*)(void *, const void*,size_t))put_membuf, tbsmb);
}
else
{
if ((string = get_parameter_value (para, pHASHALGO, 0)))
mdalgo = gcry_md_map_name (string);
else
mdalgo = GCRY_MD_SHA256;
rc = gcry_md_open (&md, mdalgo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gpg_strerror (rc));
goto leave;
}
if (DBG_HASHING)
gcry_md_debug (md, "cr.cri");
ksba_certreq_set_hash_function (cr, HASH_FNC, md);
}
if (DBG_HASHING)
gcry_md_debug (md, "cr.cri");
ksba_certreq_set_hash_function (cr, HASH_FNC, md);
ksba_certreq_set_writer (cr, writer);
err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0));
@ -1150,6 +1163,7 @@ create_request (ctrl_t ctrl,
{
unsigned char *siginfo;
err = transform_sigval (sigkey,
gcry_sexp_canon_len (sigkey, 0, NULL, NULL),
mdalgo, &siginfo, NULL);
@ -1320,6 +1334,8 @@ create_request (ctrl_t ctrl,
char hexgrip[41];
unsigned char *sigval, *newsigval;
size_t siglen;
void *tbsdata;
size_t tbsdatalen;
n = gcry_sexp_canon_len (sigkey, 0, NULL, NULL);
if (!n)
@ -1348,11 +1364,26 @@ create_request (ctrl_t ctrl,
certmode? "certificate":"CSR", hexgrip);
if (carddirect && !certmode)
rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
gcry_md_read (md, mdalgo),
gcry_md_get_algo_dlen (mdalgo),
mdalgo,
&sigval, &siglen);
{
if (tbsmb)
{
tbsdata = get_membuf (tbsmb, &tbsdatalen);
tbsmb = NULL;
if (!tbsdata)
rc = gpg_error_from_syserror ();
else
rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
tbsdata, tbsdatalen, 0,
&sigval, &siglen);
xfree (tbsdata);
}
else
rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
gcry_md_read (md, mdalgo),
gcry_md_get_algo_dlen (mdalgo),
mdalgo,
&sigval, &siglen);
}
else
{
char *orig_codeset;
@ -1364,11 +1395,25 @@ create_request (ctrl_t ctrl,
" the passphrase for the key you just created once"
" more.\n"));
i18n_switchback (orig_codeset);
rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
gcry_md_read(md, mdalgo),
gcry_md_get_algo_dlen (mdalgo),
mdalgo,
&sigval, &siglen);
if (tbsmb)
{
tbsdata = get_membuf (tbsmb, &tbsdatalen);
tbsmb = NULL;
if (!tbsdata)
rc = gpg_error_from_syserror ();
else
rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
tbsdata, tbsdatalen, 0,
&sigval, &siglen);
xfree (tbsdata);
}
else
rc = gpgsm_agent_pksign (ctrl, hexgrip, desc,
gcry_md_read(md, mdalgo),
gcry_md_get_algo_dlen (mdalgo),
mdalgo,
&sigval, &siglen);
xfree (desc);
}
if (rc)
@ -1398,6 +1443,8 @@ create_request (ctrl_t ctrl,
leave:
if (tbsmb)
xfree (get_membuf (tbsmb, NULL));
gcry_md_close (md);
ksba_certreq_release (cr);
return rc;