1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

gpgsm: Create ECC certificates with AKI and SKI by default.

* sm/certreqgen.c (create_request): Create AKI and SKI by default.
--

GnuPG-bug-id: 4098, 6253
Signed-off-by: Werner Koch <wk@gnupg.org>
Backported-from-master: 44676819f2
This commit is contained in:
Werner Koch 2020-05-19 14:30:24 +02:00
parent 9f1181e1a7
commit ed62b74a17
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
2 changed files with 163 additions and 34 deletions

View file

@ -67,6 +67,7 @@
#include "keydb.h"
#include "../common/i18n.h"
#include "../common/membuf.h"
enum para_name
@ -629,7 +630,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para,
/* Check the optional AuthorityKeyId. */
string = get_parameter_value (para, pAUTHKEYID, 0);
if (string)
if (string && strcmp (string, "none"))
{
for (s=string, i=0; hexdigitp (s); s++, i++)
;
@ -644,7 +645,7 @@ proc_parameters (ctrl_t ctrl, struct para_data_s *para,
/* Check the optional SubjectKeyId. */
string = get_parameter_value (para, pSUBJKEYID, 0);
if (string)
if (string && strcmp (string, "none"))
{
for (s=string, i=0; hexdigitp (s); s++, i++)
;
@ -835,16 +836,40 @@ create_request (ctrl_t ctrl,
ksba_isotime_t atime;
int certmode = 0;
int mdalgo;
membuf_t tbsbuffer;
membuf_t *tbsmb = NULL;
size_t publiclen;
size_t sigkeylen;
int publicpkalgo; /* The gcrypt public key algo of the public key. */
int sigkeypkalgo; /* The gcrypt public key algo of the signing key. */
err = ksba_certreq_new (&cr);
if (err)
return err;
string = get_parameter_value (para, pHASHALGO, 0);
if (string)
mdalgo = gcry_md_map_name (string);
publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
sigkeylen = sigkey? gcry_sexp_canon_len (sigkey, 0, NULL, NULL) : 0;
publicpkalgo = get_pk_algo_from_canon_sexp (public, publiclen);
sigkeypkalgo = sigkey? get_pk_algo_from_canon_sexp (public, publiclen) : 0;
if (publicpkalgo == GCRY_PK_EDDSA)
{
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
mdalgo = GCRY_MD_SHA256;
{
string = get_parameter_value (para, pHASHALGO, 0);
if (string)
mdalgo = gcry_md_map_name (string);
else
mdalgo = GCRY_MD_SHA256;
}
rc = gcry_md_open (&md, mdalgo, 0);
if (rc)
{
@ -942,12 +967,10 @@ create_request (ctrl_t ctrl,
}
}
err = ksba_certreq_set_public_key (cr, public);
if (err)
{
log_error ("error setting the public key: %s\n",
gpg_strerror (err));
log_error ("error setting the public key: %s\n", gpg_strerror (err));
rc = err;
goto leave;
}
@ -1143,14 +1166,17 @@ create_request (ctrl_t ctrl,
given we set it to the public key to create a self-signed
certificate. */
if (!sigkey)
sigkey = public;
{
sigkey = public;
sigkeylen = publiclen;
sigkeypkalgo = publicpkalgo;
}
/* Set the the digestinfo aka siginfo. */
{
unsigned char *siginfo;
err = transform_sigval (sigkey,
gcry_sexp_canon_len (sigkey, 0, NULL, NULL),
mdalgo, &siginfo, NULL);
err = transform_sigval (sigkey, sigkeylen, mdalgo, &siginfo, NULL);
if (!err)
{
err = ksba_certreq_set_siginfo (cr, siginfo);
@ -1165,9 +1191,12 @@ create_request (ctrl_t ctrl,
}
}
/* Insert the AuthorityKeyId. */
string = get_parameter_value (para, pAUTHKEYID, 0);
if (string)
if (string && !strcmp (string, "none"))
; /* Do not issue an AKI. */
else if (string)
{
char *hexbuf;
@ -1193,20 +1222,69 @@ create_request (ctrl_t ctrl,
hexbuf[2] = 0x80; /* Context tag for an implicit Octet string. */
hexbuf[3] = len;
err = ksba_certreq_add_extension (cr, oidstr_authorityKeyIdentifier,
0,
hexbuf, 4+len);
0, hexbuf, 4+len);
xfree (hexbuf);
if (err)
{
log_error ("error setting the authority-key-id: %s\n",
log_error ("error setting the AKI: %s\n", gpg_strerror (err));
goto leave;
}
}
else if (publicpkalgo == GCRY_PK_EDDSA || publicpkalgo == GCRY_PK_ECC)
{
/* For EdDSA and ECC we add the public key as default identifier. */
const unsigned char *q;
size_t qlen, derlen;
unsigned char *der;
err = get_ecc_q_from_canon_sexp (public, publiclen, &q, &qlen);
if (err)
{
log_error ("error getting Q from public key: %s\n",
gpg_strerror (err));
goto leave;
}
if (publicpkalgo == GCRY_PK_EDDSA && qlen>32 && (qlen&1) && *q==0x40)
{
/* Skip our optional native encoding octet. */
q++;
qlen--;
}
/* FIXME: For plain ECC we should better use a compressed
* point. That requires an updated Libgcrypt. Without that
* using nistp521 won't work due to the length check below. */
if (qlen > 125)
{
err = gpg_error (GPG_ERR_TOO_LARGE);
goto leave;
}
derlen = 4 + qlen;
der = xtrymalloc (derlen);
if (!der)
{
err = gpg_error_from_syserror ();
goto leave;
}
der[0] = 0x30; /* Sequence */
der[1] = qlen + 2;
der[2] = 0x80; /* Context tag for an implict Octet String. */
der[3] = qlen;
memcpy (der+4, q, qlen);
err = ksba_certreq_add_extension (cr, oidstr_authorityKeyIdentifier,
0, der, derlen);
xfree (der);
if (err)
{
log_error ("error setting the AKI: %s\n", gpg_strerror (err));
goto leave;
}
}
/* Insert the SubjectKeyId. */
string = get_parameter_value (para, pSUBJKEYID, 0);
if (string)
if (string && !strcmp (string, "none"))
; /* Do not issue an SKI. */
else if (string)
{
char *hexbuf;
@ -1234,10 +1312,53 @@ create_request (ctrl_t ctrl,
xfree (hexbuf);
if (err)
{
log_error ("error setting the subject-key-id: %s\n",
log_error ("error setting SKI: %s\n", gpg_strerror (err));
goto leave;
}
}
else if (sigkeypkalgo == GCRY_PK_EDDSA || sigkeypkalgo == GCRY_PK_ECC)
{
/* For EdDSA and ECC we add the public key as default identifier. */
const unsigned char *q;
size_t qlen, derlen;
unsigned char *der;
err = get_ecc_q_from_canon_sexp (sigkey, sigkeylen, &q, &qlen);
if (err)
{
log_error ("error getting Q from signature key: %s\n",
gpg_strerror (err));
goto leave;
}
if (sigkeypkalgo == GCRY_PK_EDDSA && qlen>32 && (qlen&1) && *q==0x40)
{
/* Skip our optional native encoding octet. */
q++;
qlen--;
}
if (qlen > 127)
{
err = gpg_error (GPG_ERR_TOO_LARGE);
goto leave;
}
derlen = 2 + qlen;
der = xtrymalloc (derlen);
if (!der)
{
err = gpg_error_from_syserror ();
goto leave;
}
der[0] = 0x04; /* Octet String */
der[1] = qlen;
memcpy (der+2, q, qlen);
err = ksba_certreq_add_extension (cr, oidstr_subjectKeyIdentifier, 0,
der, derlen);
xfree (der);
if (err)
{
log_error ("error setting the SKI: %s\n", gpg_strerror (err));
goto leave;
}
}
/* Insert additional extensions. */
@ -1313,20 +1434,12 @@ create_request (ctrl_t ctrl,
if (stopreason == KSBA_SR_NEED_SIG)
{
gcry_sexp_t s_pkey;
size_t n;
unsigned char grip[20];
char hexgrip[41];
unsigned char *sigval, *newsigval;
size_t siglen;
n = gcry_sexp_canon_len (sigkey, 0, NULL, NULL);
if (!n)
{
log_error ("libksba did not return a proper S-Exp\n");
rc = gpg_error (GPG_ERR_BUG);
goto leave;
}
rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)sigkey, n);
rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)sigkey, sigkeylen);
if (rc)
{
log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc));
@ -1342,8 +1455,9 @@ create_request (ctrl_t ctrl,
gcry_sexp_release (s_pkey);
bin2hex (grip, 20, hexgrip);
log_info ("about to sign the %s for key: &%s\n",
certmode? "certificate":"CSR", hexgrip);
if (!opt.quiet)
log_info ("about to sign the %s for key: &%s\n",
certmode? "certificate":"CSR", hexgrip);
if (carddirect && !certmode)
rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
@ -1375,8 +1489,7 @@ create_request (ctrl_t ctrl,
goto leave;
}
err = transform_sigval (sigval, siglen, mdalgo,
&newsigval, NULL);
err = transform_sigval (sigval, siglen, mdalgo, &newsigval, NULL);
xfree (sigval);
if (!err)
{