aboutsummaryrefslogtreecommitdiffstats
path: root/agent/findkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/findkey.c')
-rw-r--r--agent/findkey.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/agent/findkey.c b/agent/findkey.c
index 7b24c55ed..84d2cfdc6 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -688,7 +688,7 @@ agent_key_from_file (ctrl_t ctrl, const char *cache_nonce,
string describing the names of the parameters. ALGONAMESIZE and
ELEMSSIZE give the allocated size of the provided buffers. The
buffers may be NULL if not required. If R_LIST is not NULL the top
- level list will be stored tehre; the caller needs to release it in
+ level list will be stored there; the caller needs to release it in
this case. */
static gpg_error_t
key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
@@ -776,27 +776,65 @@ key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
}
+/* Return true if KEYPARMS holds an EdDSA key. */
+static int
+is_eddsa (gcry_sexp_t keyparms)
+{
+ int result = 0;
+ gcry_sexp_t list;
+ const char *s;
+ size_t n;
+ int i;
+
+ list = gcry_sexp_find_token (keyparms, "flags", 0);
+ for (i = list ? gcry_sexp_length (list)-1 : 0; i > 0; i--)
+ {
+ s = gcry_sexp_nth_data (list, i, &n);
+ if (!s)
+ continue; /* Not a data element. */
+
+ if (n == 5 && !memcmp (s, "eddsa", 5))
+ {
+ result = 1;
+ break;
+ }
+ }
+ gcry_sexp_release (list);
+ return result;
+}
+
+
/* Return the public key algorithm number if S_KEY is a DSA style key.
If it is not a DSA style key, return 0. */
int
agent_is_dsa_key (gcry_sexp_t s_key)
{
+ int result;
+ gcry_sexp_t list;
char algoname[6];
if (!s_key)
return 0;
- if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
+ if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
return 0; /* Error - assume it is not an DSA key. */
if (!strcmp (algoname, "dsa"))
- return GCRY_PK_DSA;
+ result = GCRY_PK_DSA;
else if (!strcmp (algoname, "ecc"))
- return GCRY_PK_ECDSA; /* FIXME: Check for the EdDSA flag. */
+ {
+ if (is_eddsa (list))
+ result = 0;
+ else
+ result = GCRY_PK_ECDSA;
+ }
else if (!strcmp (algoname, "ecdsa"))
- return GCRY_PK_ECDSA;
+ result = GCRY_PK_ECDSA;
else
- return 0;
+ result = 0;
+
+ gcry_sexp_release (list);
+ return result;
}
@@ -804,18 +842,25 @@ agent_is_dsa_key (gcry_sexp_t s_key)
int
agent_is_eddsa_key (gcry_sexp_t s_key)
{
+ int result;
+ gcry_sexp_t list;
char algoname[6];
if (!s_key)
return 0;
- if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
+ if (key_parms_from_sexp (s_key, &list, algoname, sizeof algoname, NULL, 0))
return 0; /* Error - assume it is not an EdDSA key. */
- if (!strcmp (algoname, "eddsa"))
- return 1;
+ if (!strcmp (algoname, "ecc") && is_eddsa (list))
+ result = 1;
+ else if (!strcmp (algoname, "eddsa")) /* backward compatibility. */
+ result = 1;
else
- return 0;
+ result = 0;
+
+ gcry_sexp_release (list);
+ return result;
}