mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01: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:
parent
68b857df13
commit
f44d395bdf
@ -245,6 +245,7 @@ struct certlist_s
|
||||
ksba_cert_t cert;
|
||||
int is_encrypt_to; /* True if the certificate has been set through
|
||||
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. */
|
||||
const char *hash_algo_oid; /* And the corresponding OID. */
|
||||
};
|
||||
|
81
sm/sign.c
81
sm/sign.c
@ -529,6 +529,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
||||
release_signerlist = 1;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
algorithm. */
|
||||
@ -537,6 +538,11 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
||||
for (i=0, cl=signerlist; cl; cl = cl->next, i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -545,7 +551,21 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
||||
}
|
||||
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;
|
||||
}
|
||||
switch (cl->hash_algo)
|
||||
@ -581,27 +601,23 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
||||
goto leave;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int nbits;
|
||||
int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
|
||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
|
||||
NULL, nbits, NULL))
|
||||
{
|
||||
char kidstr[10+1];
|
||||
|
||||
if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
|
||||
NULL, nbits, NULL))
|
||||
{
|
||||
char kidstr[10+1];
|
||||
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;
|
||||
}
|
||||
|
||||
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++)
|
||||
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;
|
||||
}
|
||||
rc = 0;
|
||||
{
|
||||
int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL);
|
||||
buf = xtryasprintf ("%c %d %d 00 %s %s",
|
||||
detached? 'D':'S',
|
||||
pkalgo,
|
||||
cl->hash_algo,
|
||||
signed_at,
|
||||
fpr);
|
||||
if (!buf)
|
||||
rc = gpg_error_from_syserror ();
|
||||
}
|
||||
if (opt.verbose)
|
||||
{
|
||||
char *pkalgostr = gpgsm_pubkey_algo_string (cl->cert, NULL);
|
||||
log_info (_("%s/%s signature using %s key %s\n"),
|
||||
pubkey_algo_to_string (cl->pk_algo),
|
||||
gcry_md_algo_name (cl->hash_algo),
|
||||
pkalgostr, fpr);
|
||||
xfree (pkalgostr);
|
||||
}
|
||||
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);
|
||||
if (rc)
|
||||
{
|
||||
@ -927,7 +949,6 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
|
||||
audit_log (ctrl->audit, AUDIT_SIGNING_DONE);
|
||||
log_info ("signature created\n");
|
||||
|
||||
|
||||
leave:
|
||||
if (rc)
|
||||
log_error ("error creating signature: %s <%s>\n",
|
||||
|
Loading…
x
Reference in New Issue
Block a user