1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

gpgsm: Some more ECC support backported.

* sm/certcheck.c (gpgsm_check_cert_sig): Map ECDSA OIDs.
* sm/misc.c (transform_sigval): Add ECC support.
--

GnuPG-bug-id: 6253
This commit is contained in:
Werner Koch 2022-11-14 17:10:26 +01:00
parent 3f845c8de7
commit 266a6602f0
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 94 additions and 25 deletions

View File

@ -357,9 +357,19 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert)
int use_pss = 0; int use_pss = 0;
unsigned int saltlen; unsigned int saltlen;
/* Note that we map the 4 algos which current Libgcrypt versions are
* not aware of the OID. */
algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert)));
if (!algo && algoid && !strcmp (algoid, "1.2.840.113549.1.1.10")) if (!algo && algoid && !strcmp (algoid, "1.2.840.113549.1.1.10"))
use_pss = 1; use_pss = 1;
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.1"))
algo = GCRY_MD_SHA224; /* ecdsa-with-sha224 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.2"))
algo = GCRY_MD_SHA256; /* ecdsa-with-sha256 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.3"))
algo = GCRY_MD_SHA384; /* ecdsa-with-sha384 */
else if (!algo && algoid && !strcmp (algoid, "1.2.840.10045.4.3.4"))
algo = GCRY_MD_SHA512; /* ecdsa-with-sha512 */
else if (!algo) else if (!algo)
{ {
log_error ("unknown digest algorithm '%s' used certificate\n", log_error ("unknown digest algorithm '%s' used certificate\n",

109
sm/misc.c
View File

@ -101,7 +101,7 @@ setup_pinentry_env (void)
function ignores missing parameters so that it can also be used to function ignores missing parameters so that it can also be used to
create an siginfo value as expected by ksba_certreq_set_siginfo. create an siginfo value as expected by ksba_certreq_set_siginfo.
To create a siginfo s-expression a public-key s-expression may be To create a siginfo s-expression a public-key s-expression may be
used instead of a sig-val. We only support RSA for now. */ used instead of a sig-val. */
gpg_error_t gpg_error_t
transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
unsigned char **r_newsigval, size_t *r_newsigvallen) unsigned char **r_newsigval, size_t *r_newsigvallen)
@ -111,11 +111,15 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
size_t buflen, toklen; size_t buflen, toklen;
int depth, last_depth1, last_depth2; int depth, last_depth1, last_depth2;
int is_pubkey = 0; int is_pubkey = 0;
const unsigned char *rsa_s = NULL; int pkalgo;
size_t rsa_s_len = 0; const unsigned char *rsa_s, *ecc_r, *ecc_s;
size_t rsa_s_len, ecc_r_len, ecc_s_len;
const char *oid; const char *oid;
gcry_sexp_t sexp; gcry_sexp_t sexp;
rsa_s = ecc_r = ecc_s = NULL;
rsa_s_len = ecc_r_len = ecc_s_len = 0;
*r_newsigval = NULL; *r_newsigval = NULL;
if (r_newsigvallen) if (r_newsigvallen)
*r_newsigvallen = 0; *r_newsigvallen = 0;
@ -137,7 +141,15 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
return err; return err;
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err; return err;
if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen)) if (!tok)
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
if (toklen == 3 && !memcmp ("rsa", tok, 3))
pkalgo = GCRY_PK_RSA;
else if (toklen == 3 && !memcmp ("ecc", tok, 3))
pkalgo = GCRY_PK_ECC;
else if (toklen == 5 && !memcmp ("ecdsa", tok, 5))
pkalgo = GCRY_PK_ECC;
else
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
last_depth1 = depth; last_depth1 = depth;
@ -150,8 +162,8 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
return err; return err;
if (tok && toklen == 1) if (tok && toklen == 1)
{ {
const unsigned char **mpi; const unsigned char **mpi = NULL;
size_t *mpi_len; size_t *mpi_len = NULL;
switch (*tok) switch (*tok)
{ {
@ -161,6 +173,25 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
if (mpi && *mpi) if (mpi && *mpi)
return gpg_error (GPG_ERR_DUP_VALUE); return gpg_error (GPG_ERR_DUP_VALUE);
switch (*tok)
{
case 's':
if (pkalgo == GCRY_PK_RSA)
{
mpi = &rsa_s;
mpi_len = &rsa_s_len;
}
else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
{
mpi = &ecc_s;
mpi_len = &ecc_s_len;
}
break;
case 'r': mpi = &ecc_r; mpi_len = &ecc_r_len; break;
default: mpi = NULL; mpi_len = NULL; break;
}
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err; return err;
if (tok && mpi) if (tok && mpi)
@ -181,34 +212,62 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
if (err) if (err)
return err; return err;
/* Map the hash algorithm to an OID. */ if (0)
switch (mdalgo) ; /* Just to align it with the code in 2.3. */
else
{ {
case GCRY_MD_SHA1: /* Map the hash algorithm to an OID. */
oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */ if (mdalgo < 0 || mdalgo > (1<<15) || pkalgo < 0 || pkalgo > (1<<15))
break; return gpg_error (GPG_ERR_DIGEST_ALGO);
case GCRY_MD_SHA256: switch (mdalgo | (pkalgo << 16))
oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */ {
break; case GCRY_MD_SHA1 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */
break;
case GCRY_MD_SHA384: case GCRY_MD_SHA256 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */ oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */
break; break;
case GCRY_MD_SHA512: case GCRY_MD_SHA384 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */ oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */
break; break;
default: case GCRY_MD_SHA512 | (GCRY_PK_RSA << 16):
return gpg_error (GPG_ERR_DIGEST_ALGO); oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */
break;
case GCRY_MD_SHA224 | (GCRY_PK_ECC << 16):
oid = "1.2.840.10045.4.3.1"; /* ecdsa-with-sha224 */
break;
case GCRY_MD_SHA256 | (GCRY_PK_ECC << 16):
oid = "1.2.840.10045.4.3.2"; /* ecdsa-with-sha256 */
break;
case GCRY_MD_SHA384 | (GCRY_PK_ECC << 16):
oid = "1.2.840.10045.4.3.3"; /* ecdsa-with-sha384 */
break;
case GCRY_MD_SHA512 | (GCRY_PK_ECC << 16):
oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */
break;
default:
return gpg_error (GPG_ERR_DIGEST_ALGO);
}
} }
if (rsa_s && !is_pubkey) if (is_pubkey)
err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid);
else if (pkalgo == GCRY_PK_RSA)
err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))",
oid, (int)rsa_s_len, rsa_s); oid, (int)rsa_s_len, rsa_s);
else else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid); err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(r%b)(s%b)))", oid,
(int)ecc_r_len, ecc_r, (int)ecc_s_len, ecc_s);
if (err) if (err)
return err; return err;
err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen); err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen);