1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-28 21:50:02 +02:00

sm: Support signing using ECDSA.

* sm/gpgsm.h (struct certlist_s): Add helper field pk_algo.
* sm/sign.c (gpgsm_sign): Store the public key algo.  Take the hash
algo from the curve.  Improve diagnostic output in verbose mode.
--

GnuPG-bug-id: 4098
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-05-11 18:41:21 +02:00
parent 68b857df13
commit f44d395bdf
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 52 additions and 30 deletions

View File

@ -245,6 +245,7 @@ struct certlist_s
ksba_cert_t cert; ksba_cert_t cert;
int is_encrypt_to; /* True if the certificate has been set through int is_encrypt_to; /* True if the certificate has been set through
the --encrypto-to option. */ the --encrypto-to option. */
int pk_algo; /* The PK_ALGO from CERT or 0 if not yet known. */
int hash_algo; /* Used to track the hash algorithm to use. */ int hash_algo; /* Used to track the hash algorithm to use. */
const char *hash_algo_oid; /* And the corresponding OID. */ const char *hash_algo_oid; /* And the corresponding OID. */
}; };

View File

@ -529,6 +529,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
release_signerlist = 1; release_signerlist = 1;
} }
/* Figure out the hash algorithm to use. We do not want to use the /* Figure out the hash algorithm to use. We do not want to use the
one for the certificate but if possible an OID for the plain one for the certificate but if possible an OID for the plain
algorithm. */ algorithm. */
@ -537,6 +538,11 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
for (i=0, cl=signerlist; cl; cl = cl->next, i++) for (i=0, cl=signerlist; cl; cl = cl->next, i++)
{ {
const char *oid; const char *oid;
unsigned int nbits;
int pk_algo;
pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
cl->pk_algo = pk_algo;
if (opt.forced_digest_algo) if (opt.forced_digest_algo)
{ {
@ -545,7 +551,21 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
} }
else else
{ {
oid = ksba_cert_get_digest_algo (cl->cert); if (pk_algo == GCRY_PK_ECC)
{
/* Map the Curve to a corresponding hash algo. */
if (nbits <= 256)
oid = "2.16.840.1.101.3.4.2.1"; /* sha256 */
else if (nbits <= 384)
oid = "2.16.840.1.101.3.4.2.2"; /* sha384 */
else
oid = "2.16.840.1.101.3.4.2.3"; /* sha512 */
}
else
{
/* For RSA we reuse the hash algo used by the certificate. */
oid = ksba_cert_get_digest_algo (cl->cert);
}
cl->hash_algo = oid ? gcry_md_map_name (oid) : 0; cl->hash_algo = oid ? gcry_md_map_name (oid) : 0;
} }
switch (cl->hash_algo) switch (cl->hash_algo)
@ -581,27 +601,23 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
goto leave; goto leave;
} }
{ if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
unsigned int nbits; NULL, nbits, NULL))
int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits); {
char kidstr[10+1];
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo, snprintf (kidstr, sizeof kidstr, "0x%08lX",
NULL, nbits, NULL)) gpgsm_get_short_fingerprint (cl->cert, NULL));
{ log_error (_("key %s may not be used for signing in %s mode\n"),
char kidstr[10+1]; kidstr,
gnupg_compliance_option_string (opt.compliance));
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
goto leave;
}
snprintf (kidstr, sizeof kidstr, "0x%08lX",
gpgsm_get_short_fingerprint (cl->cert, NULL));
log_error (_("key %s may not be used for signing in %s mode\n"),
kidstr,
gnupg_compliance_option_string (opt.compliance));
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
goto leave;
}
}
} }
if (opt.verbose) if (opt.verbose > 1 || opt.debug)
{ {
for (i=0, cl=signerlist; cl; cl = cl->next, i++) for (i=0, cl=signerlist; cl; cl = cl->next, i++)
log_info (_("hash algorithm used for signer %d: %s (%s)\n"), log_info (_("hash algorithm used for signer %d: %s (%s)\n"),
@ -891,17 +907,23 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
goto leave; goto leave;
} }
rc = 0; rc = 0;
{ if (opt.verbose)
int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL); {
buf = xtryasprintf ("%c %d %d 00 %s %s", char *pkalgostr = gpgsm_pubkey_algo_string (cl->cert, NULL);
detached? 'D':'S', log_info (_("%s/%s signature using %s key %s\n"),
pkalgo, pubkey_algo_to_string (cl->pk_algo),
cl->hash_algo, gcry_md_algo_name (cl->hash_algo),
signed_at, pkalgostr, fpr);
fpr); xfree (pkalgostr);
if (!buf) }
rc = gpg_error_from_syserror (); buf = xtryasprintf ("%c %d %d 00 %s %s",
} detached? 'D':'S',
cl->pk_algo,
cl->hash_algo,
signed_at,
fpr);
if (!buf)
rc = gpg_error_from_syserror ();
xfree (fpr); xfree (fpr);
if (rc) if (rc)
{ {
@ -927,7 +949,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
audit_log (ctrl->audit, AUDIT_SIGNING_DONE); audit_log (ctrl->audit, AUDIT_SIGNING_DONE);
log_info ("signature created\n"); log_info ("signature created\n");
leave: leave:
if (rc) if (rc)
log_error ("error creating signature: %s <%s>\n", log_error ("error creating signature: %s <%s>\n",