aboutsummaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
Diffstat (limited to 'sm')
-rw-r--r--sm/call-agent.c64
-rw-r--r--sm/call-dirmngr.c2
-rw-r--r--sm/certchain.c10
-rw-r--r--sm/certlist.c4
-rw-r--r--sm/certreqgen-ui.c24
-rw-r--r--sm/certreqgen.c8
-rw-r--r--sm/delete.c2
-rw-r--r--sm/export.c2
-rw-r--r--sm/gpgsm.c4
-rw-r--r--sm/gpgsm.h2
-rw-r--r--sm/keydb.c3
-rw-r--r--sm/keylist.c55
-rw-r--r--sm/minip12.c6
-rw-r--r--sm/misc.c84
-rw-r--r--sm/qualified.c2
15 files changed, 204 insertions, 68 deletions
diff --git a/sm/call-agent.c b/sm/call-agent.c
index 20d879fa4..4f2b83f56 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -334,7 +334,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
unsigned char *digest, size_t digestlen, int digestalgo,
unsigned char **r_buf, size_t *r_buflen )
{
- int rc, i;
+ int rc, i, pkalgo;
char *p, line[ASSUAN_LINELENGTH];
membuf_t data;
size_t len;
@@ -342,6 +342,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
unsigned char *sigbuf;
size_t sigbuflen;
struct default_inq_parm_s inq_parm;
+ gcry_sexp_t sig;
(void)desc;
@@ -353,6 +354,7 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
case GCRY_MD_RMD160:hashopt = "--hash=rmd160"; break;
case GCRY_MD_MD5: hashopt = "--hash=md5"; break;
case GCRY_MD_SHA256:hashopt = "--hash=sha256"; break;
+ case GCRY_MD_SHA512:hashopt = "--hash=sha512"; break;
default:
return gpg_error (GPG_ERR_DIGEST_ALGO);
}
@@ -366,6 +368,23 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
if (digestlen*2 + 50 > DIM(line))
return gpg_error (GPG_ERR_GENERAL);
+ /* Get the key type from the scdaemon. */
+ snprintf (line, DIM(line), "SCD READKEY %s", keyid);
+ init_membuf (&data, 1024);
+ rc = assuan_transact (agent_ctx, line,
+ put_membuf_cb, &data, NULL, NULL, NULL, NULL);
+ if (rc)
+ {
+ xfree (get_membuf (&data, &len));
+ return rc;
+ }
+
+ p = get_membuf (&data, &len);
+ pkalgo = get_pk_algo_from_canon_sexp (p, len);
+ xfree (p);
+ if (!pkalgo)
+ return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+
p = stpcpy (line, "SCD SETDATA " );
for (i=0; i < digestlen ; i++, p += 2 )
sprintf (p, "%02X", digest[i]);
@@ -386,24 +405,37 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
}
sigbuf = get_membuf (&data, &sigbuflen);
- /* Create an S-expression from it which is formatted like this:
- "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" Fixme: If a card ever
- creates non-RSA keys we need to change things. */
- *r_buflen = 21 + 11 + sigbuflen + 4;
- p = xtrymalloc (*r_buflen);
- *r_buf = (unsigned char*)p;
- if (!p)
+ switch(pkalgo)
{
- xfree (sigbuf);
- return 0;
+ case GCRY_PK_RSA:
+ rc = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s%b)))",
+ sigbuflen, sigbuf);
+ break;
+
+ case GCRY_PK_ECC:
+ rc = gcry_sexp_build (&sig, NULL, "(sig-val(ecdsa(r%b)(s%b)))",
+ sigbuflen/2, sigbuf,
+ sigbuflen/2, sigbuf + sigbuflen/2);
+ break;
+
+ case GCRY_PK_EDDSA:
+ rc = gcry_sexp_build (&sig, NULL, "(sig-val(eddsa(r%b)(s%b)))",
+ sigbuflen/2, sigbuf,
+ sigbuflen/2, sigbuf + sigbuflen/2);
+ break;
+
+ default:
+ rc = gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
+ break;
}
- p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
- sprintf (p, "%u:", (unsigned int)sigbuflen);
- p += strlen (p);
- memcpy (p, sigbuf, sigbuflen);
- p += sigbuflen;
- strcpy (p, ")))");
xfree (sigbuf);
+ if (rc)
+ return rc;
+
+ rc = make_canon_sexp (sig, r_buf, r_buflen);
+ gcry_sexp_release (sig);
+ if (rc)
+ return rc;
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
return 0;
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 3a38bca50..bff7dd652 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -474,7 +474,7 @@ isvalid_status_cb (void *opaque, const char *line)
{
parm->seen++;
if (!*s || !unhexify_fpr (s, parm->fpr))
- parm->seen++; /* Bumb it to indicate an error. */
+ parm->seen++; /* Bump it to indicate an error. */
}
return 0;
}
diff --git a/sm/certchain.c b/sm/certchain.c
index 4e18caf55..79d98c736 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -669,7 +669,7 @@ find_up (ctrl_t ctrl, KEYDB_HANDLE kh,
log_debug (" found via authid and sn+issuer\n");
/* In case of an error, try to get the certificate from the
- dirmngr. That is done by trying to put that certifcate
+ dirmngr. That is done by trying to put that certificate
into the ephemeral DB and let the code below do the
actual retrieve. Thus there is no error checking.
Skipped in find_next mode as usual. */
@@ -908,7 +908,7 @@ is_root_cert (ksba_cert_t cert, const char *issuerdn, const char *subjectdn)
{
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
return 1; /* Yes. Without a authorityKeyIdentifier this needs
- to be the Root certifcate (our trust anchor). */
+ to be the Root certificate (our trust anchor). */
log_error ("error getting authorityKeyIdentifier: %s\n",
gpg_strerror (err));
return 0; /* Well, it is broken anyway. Return No. */
@@ -1103,7 +1103,7 @@ check_validity_period (ksba_isotime_t current_time,
}
/* This is a variant of check_validity_period used with the chain
- model. The dextra contraint here is that notBefore and notAfter
+ model. The extra constraint here is that notBefore and notAfter
must exists and if the additional argument CHECK_TIME is given this
time is used to check the validity period of SUBJECT_CERT. */
static gpg_error_t
@@ -1171,7 +1171,7 @@ check_validity_period_cm (ksba_isotime_t current_time,
|| strcmp (check_time, not_after) > 0))
{
/* Note that we don't need a case for the root certificate
- because its own consitency has already been checked. */
+ because its own consistency has already been checked. */
do_list(opt.ignore_expiration?0:1, listmode, listfp,
depth == 0 ?
_("signature not created during lifetime of certificate") :
@@ -1553,7 +1553,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
if (rc)
goto leave;
- break; /* Okay: a self-signed certicate is an end-point. */
+ break; /* Okay: a self-signed certificate is an end-point. */
} /* End is_root. */
diff --git a/sm/certlist.c b/sm/certlist.c
index c9e275e9d..12a492518 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -395,7 +395,7 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char *name, int secret,
Further we ignore them if they are due to an
identical certificate (which may happen if a
- certificate is accidential duplicated in the
+ certificate is accidentally duplicated in the
keybox). */
if (!keydb_get_cert (kh, &cert2))
{
@@ -533,7 +533,7 @@ gpgsm_find_cert (ctrl_t ctrl,
}
/* If we don't have the KEYID filter we need to check for
- ambiguous search results. Note, that it is somehwat
+ ambiguous search results. Note, that it is somewhat
reasonable to assume that a specification of a KEYID
won't lead to ambiguous names. */
if (!rc && !keyid)
diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c
index 4f8a1ac9d..70e5739e8 100644
--- a/sm/certreqgen-ui.c
+++ b/sm/certreqgen-ui.c
@@ -86,7 +86,7 @@ store_mb_lines (membuf_t *mb, membuf_t *lines)
}
-/* Chech whether we have a key for the key with HEXGRIP. Returns NULL
+/* Check whether we have a key for the key with HEXGRIP. Returns NULL
if not or a string describing the type of the key (RSA, ELG, DSA,
etc..). */
static const char *
@@ -244,7 +244,27 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream)
{
tty_printf (_("Available keys:\n"));
for (count=1,sl=keypairlist; sl; sl = sl->next, count++)
- tty_printf (" (%d) %s\n", count, sl->d);
+ {
+ ksba_sexp_t pkey;
+ gcry_sexp_t s_pkey;
+ char *algostr = NULL;
+ const char *keyref;
+
+ keyref = strchr (sl->d, ' ');
+ if (keyref)
+ {
+ keyref++;
+ if (!gpgsm_agent_readkey (ctrl, 1, keyref, &pkey))
+ {
+ if (!gcry_sexp_new (&s_pkey, pkey, 0, 0))
+ algostr = pubkey_algo_string (s_pkey);
+ gcry_sexp_release (s_pkey);
+ }
+ xfree (pkey);
+ }
+ tty_printf (" (%d) %s %s\n", count, sl->d, algostr);
+ xfree (algostr);
+ }
xfree (answer);
answer = tty_get (_("Your selection? "));
tty_kill_prompt ();
diff --git a/sm/certreqgen.c b/sm/certreqgen.c
index 1d610c1bb..d5c857b08 100644
--- a/sm/certreqgen.c
+++ b/sm/certreqgen.c
@@ -807,8 +807,10 @@ create_request (ctrl_t ctrl,
if (err)
return err;
- string = get_parameter_value (para, pHASHALGO, 0);
- if (string)
+ 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;
@@ -1312,7 +1314,7 @@ create_request (ctrl_t ctrl,
log_info ("about to sign the %s for key: &%s\n",
certmode? "certificate":"CSR", hexgrip);
- if (carddirect)
+ if (carddirect && !certmode)
rc = gpgsm_scd_pksign (ctrl, carddirect, NULL,
gcry_md_read (md, mdalgo),
gcry_md_get_algo_dlen (mdalgo),
diff --git a/sm/delete.c b/sm/delete.c
index 56d5b1f8c..f359cc595 100644
--- a/sm/delete.c
+++ b/sm/delete.c
@@ -64,8 +64,6 @@ delete_one (ctrl_t ctrl, const char *username)
/* If the key is specified in a unique way, include ephemeral keys
in the search. */
if ( desc.mode == KEYDB_SEARCH_MODE_FPR
- || desc.mode == KEYDB_SEARCH_MODE_FPR20
- || desc.mode == KEYDB_SEARCH_MODE_FPR16
|| desc.mode == KEYDB_SEARCH_MODE_KEYGRIP )
{
is_ephem = 1;
diff --git a/sm/export.c b/sm/export.c
index 7bea9ccc5..918096e7c 100644
--- a/sm/export.c
+++ b/sm/export.c
@@ -198,8 +198,6 @@ gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream)
{
for (i=0; (i < ndesc
&& (desc[i].mode == KEYDB_SEARCH_MODE_FPR
- || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
- || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
|| desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
;
if (i == ndesc)
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index b0547876a..2f9e5bfd2 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -1571,7 +1571,7 @@ main ( int argc, char **argv)
set_debug ();
- /* Although we always use gpgsm_exit, we better install a regualr
+ /* Although we always use gpgsm_exit, we better install a regular
exit handler so that at least the secure memory gets wiped
out. */
if (atexit (emergency_cleanup))
@@ -1666,7 +1666,7 @@ main ( int argc, char **argv)
|| cmd == aClearsign,
opt.extra_digest_algo))
log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
- forced_digest_algo,
+ extra_digest_algo,
gnupg_compliance_option_string (opt.compliance));
if (log_get_errorcount(0))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index d3fbde515..7a5e4917d 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -76,7 +76,7 @@ struct
const char *protect_tool_program;
char *outfile; /* name of output file */
- int with_key_data;/* include raw key in the column delimted output */
+ int with_key_data;/* include raw key in the column delimited output */
int fingerprint; /* list fingerprints in all key listings */
diff --git a/sm/keydb.c b/sm/keydb.c
index d85679a3b..f66a5766d 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -106,7 +106,7 @@ try_make_homedir (const char *fname)
/* Handle the creation of a keybox if it does not yet exist. Take
- into acount that other processes might have the keybox already
+ into account that other processes might have the keybox already
locked. This lock check does not work if the directory itself is
not yet available. If R_CREATED is not NULL it will be set to true
if the function created a new keybox. */
@@ -1052,6 +1052,7 @@ keydb_search_fpr (ctrl_t ctrl, KEYDB_HANDLE hd, const byte *fpr)
memset (&desc, 0, sizeof desc);
desc.mode = KEYDB_SEARCH_MODE_FPR;
memcpy (desc.u.fpr, fpr, 20);
+ desc.fprlen = 20;
return keydb_search (ctrl, hd, &desc, 1);
}
diff --git a/sm/keylist.c b/sm/keylist.c
index ea2a22093..e242310be 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -85,6 +85,8 @@ struct
#define OID_FLAG_SKIP 1
/* The extension is a simple UTF8String and should be printed. */
#define OID_FLAG_UTF8 2
+/* The extension can be trnted as a hex string. */
+#define OID_FLAG_HEX 4
/* A table mapping OIDs to a descriptive string. */
static struct
@@ -194,6 +196,12 @@ static struct
/* Extensions used by the Bundesnetzagentur. */
{ "1.3.6.1.4.1.8301.3.5", "validityModel" },
+ /* Yubikey extensions for attestation certificates. */
+ { "1.3.6.1.4.1.41482.3.3", "yubikey-firmware-version", OID_FLAG_HEX },
+ { "1.3.6.1.4.1.41482.3.7", "yubikey-serial-number", OID_FLAG_HEX },
+ { "1.3.6.1.4.1.41482.3.8", "yubikey-pin-touch-policy", OID_FLAG_HEX },
+ { "1.3.6.1.4.1.41482.3.9", "yubikey-formfactor", OID_FLAG_HEX },
+
{ NULL }
};
@@ -384,16 +392,21 @@ static void
print_compliance_flags (ksba_cert_t cert, int algo, unsigned int nbits,
estream_t fp)
{
- int any = 0;
+ int indent = 0;
+ int hashalgo;
if (gnupg_pk_is_compliant (CO_DE_VS, algo, NULL, nbits, NULL))
{
- es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
- any++;
+ hashalgo = gcry_md_map_name (ksba_cert_get_digest_algo (cert));
+ if (gnupg_digest_is_compliant (CO_DE_VS, hashalgo))
+ {
+ es_fputs (gnupg_status_compliance_flag (CO_DE_VS), fp);
+ indent = 1;
+ }
}
if (opt.with_key_screening)
- print_pk_screening (cert, 1+any, fp);
+ print_pk_screening (cert, 1+indent, fp);
}
@@ -718,6 +731,21 @@ print_utf8_extn (estream_t fp, int indent,
}
+/* Print the extension described by (DER,DERLEN) in hex. */
+static void
+print_hex_extn (estream_t fp, int indent,
+ const unsigned char *der, size_t derlen)
+{
+ if (indent < 0)
+ indent = - indent;
+
+ es_fprintf (fp, "%*s(", indent, "");
+ for (; derlen; der++, derlen--)
+ es_fprintf (fp, "%02X%s", *der, derlen > 1? " ":"");
+ es_fprintf (fp, ")\n");
+}
+
+
/* List one certificate in raw mode useful to have a closer look at
the certificate. This one does no beautification and only minimal
output sanitation. It is mainly useful for debugging. */
@@ -1055,16 +1083,27 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
if ((flag & OID_FLAG_SKIP))
continue;
- es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n",
+ es_fprintf (fp, " %s: %s%s%s%s",
i? "critExtn":" extn",
- oid, s?" (":"", s?s:"", s?")":"", (int)len);
+ oid, s?" (":"", s?s:"", s?")":"");
if ((flag & OID_FLAG_UTF8))
{
if (!cert_der)
cert_der = ksba_cert_get_image (cert, NULL);
- assert (cert_der);
+ log_assert (cert_der);
+ es_fprintf (fp, "\n");
print_utf8_extn_raw (fp, -15, cert_der+off, len);
}
+ else if ((flag & OID_FLAG_HEX))
+ {
+ if (!cert_der)
+ cert_der = ksba_cert_get_image (cert, NULL);
+ log_assert (cert_der);
+ es_fprintf (fp, "\n");
+ print_hex_extn (fp, -15, cert_der+off, len);
+ }
+ else
+ es_fprintf (fp, " [%d octets]\n", (int)len);
}
@@ -1438,8 +1477,6 @@ list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
for (i=0; (i < ndesc
&& (desc[i].mode == KEYDB_SEARCH_MODE_FPR
- || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
- || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
|| desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
;
if (i == ndesc)
diff --git a/sm/minip12.c b/sm/minip12.c
index f066892a0..76ce07376 100644
--- a/sm/minip12.c
+++ b/sm/minip12.c
@@ -853,7 +853,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length,
if (ti.class == ASNCONTEXT && ti.tag == 0 && ti.is_constructed && ti.ndef)
{
/* Mozilla exported certs now come with single byte chunks of
- octect strings. (Mozilla Firefox 1.0.4). Arghh. */
+ octet strings. (Mozilla Firefox 1.0.4). Arghh. */
where = "cram-rc2or3des-ciphertext";
cram_buffer = cram_octet_string ( p, &n, &consumed);
if (!cram_buffer)
@@ -1210,7 +1210,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset,
if (ti.is_constructed && ti.ndef)
{
/* Mozilla exported certs now come with single byte chunks of
- octect strings. (Mozilla Firefox 1.0.4). Arghh. */
+ octet strings. (Mozilla Firefox 1.0.4). Arghh. */
where = "cram-data.outersegs";
cram_buffer = cram_octet_string ( p, &n, &consumed);
if (!cram_buffer)
@@ -1550,7 +1550,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw,
if (ti.is_constructed && ti.ndef)
{
/* Mozilla exported certs now come with single byte chunks of
- octect strings. (Mozilla Firefox 1.0.4). Arghh. */
+ octet strings. (Mozilla Firefox 1.0.4). Arghh. */
where = "cram-bags";
cram_buffer = cram_octet_string ( p, &n, NULL);
if (!cram_buffer)
diff --git a/sm/misc.c b/sm/misc.c
index 6d047763b..954529390 100644
--- a/sm/misc.c
+++ b/sm/misc.c
@@ -109,13 +109,16 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
gpg_error_t err;
const unsigned char *buf, *tok;
size_t buflen, toklen;
- int depth, last_depth1, last_depth2;
+ int depth, last_depth1, last_depth2, pkalgo;
int is_pubkey = 0;
- const unsigned char *rsa_s = NULL;
- 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;
gcry_sexp_t sexp;
+ rsa_s = ecc_r = ecc_s = NULL;
+ rsa_s_len = ecc_r_len = ecc_s_len = 0;
+
*r_newsigval = NULL;
if (r_newsigvallen)
*r_newsigvallen = 0;
@@ -137,7 +140,15 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
return err;
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
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 == 5 && !memcmp ("ecdsa", tok, 5))
+ pkalgo = GCRY_PK_ECC;
+ else if (toklen == 5 && !memcmp ("eddsa", tok, 5))
+ pkalgo = GCRY_PK_EDDSA;
+ else
return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
last_depth1 = depth;
@@ -150,16 +161,27 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
return err;
if (tok && toklen == 1)
{
- const unsigned char **mpi;
- size_t *mpi_len;
+ const unsigned char **mpi = NULL;
+ size_t *mpi_len = NULL;
switch (*tok)
{
- case 's': mpi = &rsa_s; mpi_len = &rsa_s_len; break;
+ 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 (mpi && *mpi)
- return gpg_error (GPG_ERR_DUP_VALUE);
if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
return err;
@@ -182,33 +204,59 @@ transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
return err;
/* Map the hash algorithm to an OID. */
- switch (mdalgo)
+ if (mdalgo < 0 || mdalgo > (1<<15) || pkalgo < 0 || pkalgo > (1<<15))
+ return gpg_error (GPG_ERR_DIGEST_ALGO);
+
+ switch (mdalgo | (pkalgo << 16))
{
- case GCRY_MD_SHA1:
+ case GCRY_MD_SHA1 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */
break;
- case GCRY_MD_SHA256:
+ case GCRY_MD_SHA256 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */
break;
- case GCRY_MD_SHA384:
+ case GCRY_MD_SHA384 | (GCRY_PK_RSA << 16):
oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */
break;
- case GCRY_MD_SHA512:
+ case GCRY_MD_SHA512 | (GCRY_PK_RSA << 16):
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;
+
+ case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 16):
+ oid = "1.3.101.112"; /* ed25519 */
+ break;
+
default:
return gpg_error (GPG_ERR_DIGEST_ALGO);
}
- if (rsa_s && !is_pubkey)
- err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))",
- oid, (int)rsa_s_len, rsa_s);
- else
+ 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)))", oid,
+ (int)rsa_s_len, rsa_s);
+ else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
+ 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)
return err;
err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen);
diff --git a/sm/qualified.c b/sm/qualified.c
index 6a7b47306..70d03aed3 100644
--- a/sm/qualified.c
+++ b/sm/qualified.c
@@ -140,7 +140,7 @@ read_list (char *key, char *country, int *lnr)
Returns: 0 if the certificate is included. GPG_ERR_NOT_FOUND if it
is not in the list or any other error (e.g. if no list of
qualified signatures is available. If COUNTRY has not been passed
- as NULL a string witha maximum length of 2 will be copied into it;
+ as NULL a string with a maximum length of 2 will be copied into it;
thus the caller needs to provide a buffer of length 3. */
gpg_error_t
gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert, char *country)