aboutsummaryrefslogtreecommitdiffstats
path: root/agent/findkey.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2010-04-21 16:26:17 +0000
committerWerner Koch <[email protected]>2010-04-21 16:26:17 +0000
commita1412b05debe693e6aabaf2c2c337bc33f7dfd41 (patch)
tree214dc8928b73aaa385d69eaa180164318ff0bb93 /agent/findkey.c
parentDisable card support for now (diff)
downloadgnupg-a1412b05debe693e6aabaf2c2c337bc33f7dfd41.tar.gz
gnupg-a1412b05debe693e6aabaf2c2c337bc33f7dfd41.zip
More changes on the way to remove secring.gpg.
Diffstat (limited to 'agent/findkey.c')
-rw-r--r--agent/findkey.c154
1 files changed, 108 insertions, 46 deletions
diff --git a/agent/findkey.c b/agent/findkey.c
index 30aa7c938..d6478ac4d 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -1,6 +1,6 @@
/* findkey.c - Locate the secret key
- * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- * 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
+ * 2010 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -626,50 +626,32 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text,
}
-
-/* Return the public key for the keygrip GRIP. The result is stored
- at RESULT. This function extracts the public key from the private
- key database. On failure an error code is returned and NULL stored
- at RESULT. */
-gpg_error_t
-agent_public_key_from_file (ctrl_t ctrl,
- const unsigned char *grip,
- gcry_sexp_t *result)
+/* Return the string name from the S-expression S_KEY as well as a
+ 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
+ this case. */
+static gpg_error_t
+key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list,
+ char *r_algoname, size_t algonamesize,
+ char *r_elems, size_t elemssize)
{
- int i, idx, rc;
- gcry_sexp_t s_skey;
- const char *algoname;
- gcry_sexp_t uri_sexp, comment_sexp;
- const char *uri, *comment;
- size_t uri_length, comment_length;
- char *format, *p;
- void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
- for comment + end-of-list. */
- int argidx;
gcry_sexp_t list, l2;
- const char *name;
- const char *s;
+ const char *name, *algoname, *elems;
size_t n;
- const char *elems;
- gcry_mpi_t *array;
-
- (void)ctrl;
-
- *result = NULL;
- rc = read_key_file (grip, &s_skey);
- if (rc)
- return rc;
+ if (r_list)
+ *r_list = NULL;
- list = gcry_sexp_find_token (s_skey, "shadowed-private-key", 0 );
+ list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
if (!list)
- list = gcry_sexp_find_token (s_skey, "protected-private-key", 0 );
+ list = gcry_sexp_find_token (s_key, "protected-private-key", 0 );
if (!list)
- list = gcry_sexp_find_token (s_skey, "private-key", 0 );
+ list = gcry_sexp_find_token (s_key, "private-key", 0 );
if (!list)
{
log_error ("invalid private key format\n");
- gcry_sexp_release (s_skey);
return gpg_error (GPG_ERR_BAD_SECKEY);
}
@@ -696,19 +678,99 @@ agent_public_key_from_file (ctrl_t ctrl,
{
log_error ("unknown private key algorithm\n");
gcry_sexp_release (list);
- gcry_sexp_release (s_skey);
return gpg_error (GPG_ERR_BAD_SECKEY);
}
+ if (r_algoname)
+ {
+ if (strlen (algoname) >= algonamesize)
+ return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+ strcpy (r_algoname, algoname);
+ }
+ if (r_elems)
+ {
+ if (strlen (elems) >= elemssize)
+ return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
+ strcpy (r_elems, elems);
+ }
+
+ if (r_list)
+ *r_list = list;
+ else
+ gcry_sexp_release (list);
+
+ return 0;
+}
+
+
+/* Return true if S_KEY is a DSA style key. */
+int
+agent_is_dsa_key (gcry_sexp_t s_key)
+{
+ char algoname[6];
+
+ if (!s_key)
+ return 0;
+
+ if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0))
+ return 0; /* Error - assume it is not an DSA key. */
+
+ return (!strcmp (algoname, "dsa") || !strcmp (algoname, "ecdsa"));
+}
+
+
+
+/* Return the public key for the keygrip GRIP. The result is stored
+ at RESULT. This function extracts the public key from the private
+ key database. On failure an error code is returned and NULL stored
+ at RESULT. */
+gpg_error_t
+agent_public_key_from_file (ctrl_t ctrl,
+ const unsigned char *grip,
+ gcry_sexp_t *result)
+{
+ gpg_error_t err;
+ int i, idx;
+ gcry_sexp_t s_skey;
+ char algoname[6];
+ char elems[6];
+ gcry_sexp_t uri_sexp, comment_sexp;
+ const char *uri, *comment;
+ size_t uri_length, comment_length;
+ char *format, *p;
+ void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2
+ for comment + end-of-list. */
+ int argidx;
+ gcry_sexp_t list, l2;
+ const char *s;
+ gcry_mpi_t *array;
+
+ (void)ctrl;
+
+ *result = NULL;
+
+ err = read_key_file (grip, &s_skey);
+ if (err)
+ return err;
+
+ err = key_parms_from_sexp (s_skey, &list,
+ algoname, sizeof algoname,
+ elems, sizeof elems);
+ if (err)
+ {
+ gcry_sexp_release (s_skey);
+ return err;
+ }
+
/* Allocate an array for the parameters and copy them out of the
secret key. FIXME: We should have a generic copy function. */
array = xtrycalloc (strlen(elems) + 1, sizeof *array);
if (!array)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
gcry_sexp_release (list);
gcry_sexp_release (s_skey);
- return rc;
+ return err;
}
for (idx=0, s=elems; *s; s++, idx++ )
@@ -757,8 +819,8 @@ agent_public_key_from_file (ctrl_t ctrl,
/* FIXME: The following thing is pretty ugly code; we should
- investigate how to make it cleaner. Probably code to handle
- canonical S-expressions in a memory buffer is better suioted for
+ investigate how to make it cleaner. Probably code to handle
+ canonical S-expressions in a memory buffer is better suited for
such a task. After all that is what we do in protect.c. Neeed
to find common patterns and write a straightformward API to use
them. */
@@ -767,13 +829,13 @@ agent_public_key_from_file (ctrl_t ctrl,
format = xtrymalloc (15+7*strlen (elems)+10+15+1+1);
if (!format)
{
- rc = gpg_error_from_syserror ();
+ err = gpg_error_from_syserror ();
for (i=0; array[i]; i++)
gcry_mpi_release (array[i]);
xfree (array);
gcry_sexp_release (uri_sexp);
gcry_sexp_release (comment_sexp);
- return rc;
+ return err;
}
argidx = 0;
@@ -806,7 +868,7 @@ agent_public_key_from_file (ctrl_t ctrl,
assert (argidx < DIM (args));
args[argidx] = NULL;
- rc = gcry_sexp_build_array (&list, NULL, format, args);
+ err = gcry_sexp_build_array (&list, NULL, format, args);
xfree (format);
for (i=0; array[i]; i++)
gcry_mpi_release (array[i]);
@@ -814,9 +876,9 @@ agent_public_key_from_file (ctrl_t ctrl,
gcry_sexp_release (uri_sexp);
gcry_sexp_release (comment_sexp);
- if (!rc)
+ if (!err)
*result = list;
- return rc;
+ return err;
}