aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2002-06-17 10:11:34 +0000
committerWerner Koch <[email protected]>2002-06-17 10:11:34 +0000
commit469dc1043df7cba113fedfbd10c1ad4052d9d6ee (patch)
tree84a2a73d1f9ad60fd6eb2b080efb84f41e72237f
parent* card-dinsig.c: Documented some stuff from the DIN norm. (diff)
downloadgnupg-469dc1043df7cba113fedfbd10c1ad4052d9d6ee.tar.gz
gnupg-469dc1043df7cba113fedfbd10c1ad4052d9d6ee.zip
* agent.h: Add a callback function to the pin_entry_info structure.
* query.c (agent_askpin): Use the callback to check for a correct PIN. Removed the start_err_text argument becuase it is not anymore needed; changed callers. * findkey.c (unprotect): Replace our own check loop by a callback. (try_unprotect_cb): New. * genkey.c (reenter_compare_cb): New. (agent_genkey): Use this callback here. Fixed setting of the pi2 variable and a segv in case of an empty PIN. * divert-scd.c (getpin_cb): Removed some unused stuff and explained what we still have to change.
Diffstat (limited to '')
-rw-r--r--agent/ChangeLog15
-rw-r--r--agent/agent.h6
-rw-r--r--agent/divert-scd.c26
-rw-r--r--agent/findkey.c56
-rw-r--r--agent/genkey.c38
-rw-r--r--agent/query.c56
6 files changed, 118 insertions, 79 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 2355e4926..7ab1ac640 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,18 @@
+2002-06-17 Werner Koch <[email protected]>
+
+ * agent.h: Add a callback function to the pin_entry_info structure.
+ * query.c (agent_askpin): Use the callback to check for a correct
+ PIN. Removed the start_err_text argument becuase it is not
+ anymore needed; changed callers.
+ * findkey.c (unprotect): Replace our own check loop by a callback.
+ (try_unprotect_cb): New.
+ * genkey.c (reenter_compare_cb): New.
+ (agent_genkey): Use this callback here. Fixed setting of the pi2
+ variable and a segv in case of an empty PIN.
+
+ * divert-scd.c (getpin_cb): Removed some unused stuff and
+ explained what we still have to change.
+
2002-06-12 Werner Koch <[email protected]>
* gpg-agent.c (main): New option --disable-pth.
diff --git a/agent/agent.h b/agent/agent.h
index 44b383211..75683a0ad 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -85,6 +85,9 @@ struct pin_entry_info_s {
int max_digits; /* max. number of allowed digits allowed*/
int max_tries;
int failed_tries;
+ int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */
+ void *check_cb_arg; /* optional argument which might be of use in the CB */
+ const char *cb_errtext; /* used by the cb to displaye a specific error */
size_t max_length; /* allocated length of the buffer */
char pin[1];
};
@@ -114,8 +117,7 @@ GCRY_SEXP agent_key_from_file (const unsigned char *grip,
int agent_key_available (const unsigned char *grip);
/*-- query.c --*/
-int agent_askpin (const char *desc_text, const char *err_text,
- struct pin_entry_info_s *pininfo);
+int agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo);
int agent_get_passphrase (char **retpass,
const char *desc, const char *prompt,
const char *errtext);
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index ba0fa6edf..f2a26acc7 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -166,7 +166,7 @@ encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo,
/* Callback used to ask for the PIN which should be set into BUF. The
buf has been allocated by the caller and is of size MAXBUF which
includes the terminating null. The function should return an UTF-8
- string with the passphrase, the buffer may optioanlly be padded
+ string with the passphrase, the buffer may optionally be padded
with arbitrary characters */
static int
getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
@@ -174,35 +174,27 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
struct pin_entry_info_s *pi;
int rc;
int tries = 0;
- const char *errtext;
-
+
assert (!opaque);
if (maxbuf < 2)
return GNUPG_Invalid_Value;
- /* FIXME: keep PI and TRIES in OPAQUE */
+ /* FIXME: keep PI and TRIES in OPAQUE. Actually this is a whole
+ mess becuase we should call the card's verify function from the
+ pinentry check pin CB. */
pi = gcry_calloc_secure (1, sizeof (*pi) + 100);
pi->max_length = maxbuf-1;
pi->min_digits = 0; /* we want a real passphrase */
pi->max_digits = 8;
pi->max_tries = 3;
- errtext = NULL;
- do
+ rc = agent_askpin (info, pi);
+ if (!rc)
{
- rc = agent_askpin (info, errtext, pi);
- if (!rc)
- {
- strncpy (buf, pi->pin, maxbuf-1);
- buf[maxbuf-1] = 0;
- xfree (pi);
- return 0;
- }
- errtext = pi->min_digits? trans ("Bad PIN") : trans ("Bad Passphrase");
+ strncpy (buf, pi->pin, maxbuf-1);
+ buf[maxbuf-1] = 0;
}
- while ((rc == GNUPG_Bad_Passphrase || rc == GNUPG_Bad_PIN)
- && tries++ < 3);
xfree (pi);
return rc;
}
diff --git a/agent/findkey.c b/agent/findkey.c
index 1a222ba77..3a9dd53b8 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -27,9 +27,17 @@
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <assert.h>
#include "agent.h"
+/* Helper to pass data to the check callback of the unprotect function. */
+struct try_unprotect_arg_s {
+ const unsigned char *protected_key;
+ unsigned char *unprotected_key;
+};
+
+
int
agent_write_private_key (const unsigned char *grip,
@@ -88,16 +96,32 @@ agent_write_private_key (const unsigned char *grip,
}
+/* Callback function to try the unprotection from the passpharse query
+ code. */
+static int
+try_unprotect_cb (struct pin_entry_info_s *pi)
+{
+ struct try_unprotect_arg_s *arg = pi->check_cb_arg;
+ size_t dummy;
+
+ assert (!arg->unprotected_key);
+ return agent_unprotect (arg->protected_key, pi->pin,
+ &arg->unprotected_key, &dummy);
+}
+
+
+/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
+ should be the hex encoded keygrip of that key to be used with the
+ cahing mechanism. */
static int
unprotect (unsigned char **keybuf, const unsigned char *grip)
{
struct pin_entry_info_s *pi;
+ struct try_unprotect_arg_s arg;
int rc, i;
unsigned char *result;
size_t resultlen;
- int tries = 0;
char hexgrip[40+1];
- const char *errtext;
for (i=0; i < 20; i++)
sprintf (hexgrip+2*i, "%02X", grip[i]);
@@ -127,27 +151,19 @@ unprotect (unsigned char **keybuf, const unsigned char *grip)
pi->min_digits = 0; /* we want a real passphrase */
pi->max_digits = 8;
pi->max_tries = 3;
+ pi->check_cb = try_unprotect_cb;
+ arg.protected_key = *keybuf;
+ arg.unprotected_key = NULL;
+ pi->check_cb_arg = &arg;
- errtext = NULL;
- do
+ rc = agent_askpin (NULL, pi);
+ if (!rc)
{
- rc = agent_askpin (NULL, errtext, pi);
- if (!rc)
- {
- rc = agent_unprotect (*keybuf, pi->pin, &result, &resultlen);
- if (!rc)
- {
- agent_put_cache (hexgrip, pi->pin, 0);
- xfree (*keybuf);
- *keybuf = result;
- xfree (pi);
- return 0;
- }
- }
- errtext = pi->min_digits? trans ("Bad PIN") : trans ("Bad Passphrase");
+ assert (arg.unprotected_key);
+ agent_put_cache (hexgrip, pi->pin, 0);
+ xfree (*keybuf);
+ *keybuf = arg.unprotected_key;
}
- while ((rc == GNUPG_Bad_Passphrase || rc == GNUPG_Bad_PIN)
- && tries++ < 3);
xfree (pi);
return rc;
}
diff --git a/agent/genkey.c b/agent/genkey.c
index ae46c4694..630e0e30d 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -70,6 +70,19 @@ store_key (GCRY_SEXP private, const char *passphrase)
return rc;
}
+/* Callback function to compare the first entered PIN with the one
+ currently beeing entered. */
+static int
+reenter_compare_cb (struct pin_entry_info_s *pi)
+{
+ const char *pin1 = pi->check_cb_arg;
+
+ if (!strcmp (pin1, pi->pin))
+ return 0; /* okay */
+ pi->cb_errtext = trans ("does not match - try again");
+ return -1;
+}
+
/* Generate a new keypair according to the parameters given in
@@ -91,39 +104,30 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
return seterr (Invalid_Data);
}
- /* Get the passphrase now, cause key generation may take a while */
+ /* Get the passphrase now, cause key generation may take a while. */
{
const char *text1 = trans ("Please enter the passphrase to%0A"
"to protect your new key");
const char *text2 = trans ("Please re-enter this passphrase");
- const char *nomatch = trans ("does not match - try again");
- int tries = 0;
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
- pi2 = pi + sizeof *pi;
+ pi2 = pi + (sizeof *pi + 100);
pi->max_length = 100;
pi->max_tries = 3;
pi2->max_length = 100;
pi2->max_tries = 3;
+ pi2->check_cb = reenter_compare_cb;
+ pi2->check_cb_arg = pi->pin;
- rc = agent_askpin (text1, NULL, pi);
+ rc = agent_askpin (text1, pi);
if (!rc)
- {
- do
- {
- rc = agent_askpin (text2, tries? nomatch:NULL, pi2);
- tries++;
- }
- while (!rc && tries < 3 && strcmp (pi->pin, pi2->pin));
- if (!rc && strcmp (pi->pin, pi2->pin))
- rc = GNUPG_Canceled;
- }
+ rc = agent_askpin (text2, pi2);
if (rc)
return rc;
if (!*pi->pin)
{
xfree (pi);
- pi = NULL; /* use does not want a passphrase */
+ pi = NULL; /* User does not want a passphrase. */
}
}
@@ -158,7 +162,7 @@ agent_genkey (CTRL ctrl, const char *keyparam, size_t keyparamlen,
/* store the secret key */
log_debug ("storing private key\n");
- rc = store_key (s_private, pi->pin);
+ rc = store_key (s_private, pi? pi->pin:NULL);
xfree (pi); pi = NULL;
gcry_sexp_release (s_private);
if (rc)
diff --git a/agent/query.c b/agent/query.c
index af513b819..724bbd57d 100644
--- a/agent/query.c
+++ b/agent/query.c
@@ -218,13 +218,12 @@ all_digitsp( const char *s)
number here and repeat it as long as we have invalid formed
numbers. */
int
-agent_askpin (const char *desc_text, const char *start_err_text,
- struct pin_entry_info_s *pininfo)
+agent_askpin (const char *desc_text, struct pin_entry_info_s *pininfo)
{
int rc;
char line[ASSUAN_LINELENGTH];
struct entry_parm_s parm;
- const char *errtext = start_err_text;
+ const char *errtext = NULL;
if (opt.batch)
return 0; /* fixme: we should return BAD PIN */
@@ -261,14 +260,8 @@ agent_askpin (const char *desc_text, const char *start_err_text,
if (errtext)
{
/* fixme: should we show the try count? It must be translated */
- if (start_err_text)
- {
- snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
- start_err_text = NULL;
- }
- else
- snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)",
- errtext, pininfo->failed_tries+1, pininfo->max_tries);
+ snprintf (line, DIM(line)-1, "SETERROR %s (try %d of %d)",
+ errtext, pininfo->failed_tries+1, pininfo->max_tries);
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
@@ -276,25 +269,42 @@ agent_askpin (const char *desc_text, const char *start_err_text,
errtext = NULL;
}
- rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
+ rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
+ NULL, NULL, NULL, NULL);
if (rc == ASSUAN_Too_Much_Data)
errtext = pininfo->min_digits? trans ("PIN too long")
: trans ("Passphrase too long");
else if (rc)
return unlock_pinentry (map_assuan_err (rc));
- if (!errtext && !pininfo->min_digits)
- return unlock_pinentry (0); /* okay, got a passphrase */
- if (!errtext && !all_digitsp (pininfo->pin))
- errtext = trans ("Invalid characters in PIN");
- if (!errtext && pininfo->max_digits
- && strlen (pininfo->pin) > pininfo->max_digits)
- errtext = trans ("PIN too long");
- if (!errtext
- && strlen (pininfo->pin) < pininfo->min_digits)
- errtext = trans ("PIN too short");
+
+ if (!errtext && pininfo->min_digits)
+ {
+ /* do some basic checks on the entered PIN. */
+ if (!all_digitsp (pininfo->pin))
+ errtext = trans ("Invalid characters in PIN");
+ else if (pininfo->max_digits
+ && strlen (pininfo->pin) > pininfo->max_digits)
+ errtext = trans ("PIN too long");
+ else if (strlen (pininfo->pin) < pininfo->min_digits)
+ errtext = trans ("PIN too short");
+ }
+
+ if (!errtext && pininfo->check_cb)
+ {
+ /* More checks by utilizing the optional callback. */
+ pininfo->cb_errtext = NULL;
+ rc = pininfo->check_cb (pininfo);
+ if (rc == -1 && pininfo->cb_errtext)
+ errtext = pininfo->cb_errtext;
+ else if (rc == GNUPG_Bad_Passphrase || rc == GNUPG_Bad_PIN)
+ errtext = (pininfo->min_digits? trans ("Bad PIN")
+ : trans ("Bad Passphrase"));
+ else if (rc)
+ return unlock_pinentry (map_assuan_err (rc));
+ }
if (!errtext)
- return unlock_pinentry (0); /* okay, got a PIN */
+ return unlock_pinentry (0); /* okay, got a PIN or passphrase */
}
return unlock_pinentry (pininfo->min_digits? GNUPG_Bad_PIN