[svn] GnuPG - r4391 - trunk/scd
svn author wk
cvs at cvs.gnupg.org
Thu Dec 21 13:13:45 CET 2006
Author: wk
Date: 2006-12-21 13:13:44 +0100 (Thu, 21 Dec 2006)
New Revision: 4391
Modified:
trunk/scd/ChangeLog
trunk/scd/app-openpgp.c
Log:
The keypad is now also used for OpenPGP signing keys.
Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog 2006-12-21 08:05:29 UTC (rev 4390)
+++ trunk/scd/ChangeLog 2006-12-21 12:13:44 UTC (rev 4391)
@@ -1,3 +1,11 @@
+2006-12-21 Werner Koch <wk at g10code.com>
+
+ * app-openpgp.c (verify_chv2): Factored most code out into...
+ (verify_a_chv): ... new.
+ (do_sign): Factored verification code out to new function and
+ take care of a keypad entered PIN.
+ (compare_fingerprint): Print an additional diagnostic.
+
2006-11-28 Werner Koch <wk at g10code.com>
* apdu.c (send_le, apdu_send_direct): Increase RESULTLEN to 258 to
Modified: trunk/scd/app-openpgp.c
===================================================================
--- trunk/scd/app-openpgp.c 2006-12-21 08:05:29 UTC (rev 4390)
+++ trunk/scd/app-openpgp.c 2006-12-21 12:13:44 UTC (rev 4391)
@@ -1277,94 +1277,164 @@
}
-
-/* Verify CHV2 if required. Depending on the configuration of the
- card CHV1 will also be verified. */
+/* Verify a CHV either using using the pinentry or if possibile by
+ using a keypad. PINCB and PINCB_ARG describe the usual callback
+ for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only
+ ised with CHV1. PINVALUE is the address of a pointer which will
+ receive a newly allocated block with the actual PIN (this is useful
+ in case that PIN shall be used for another verifiy operation). The
+ caller needs to free this value. If the function returns with
+ success and NULL is stored at PINVALUE, the caller should take this
+ as an indication that the keypad has been used.
+ */
static gpg_error_t
-verify_chv2 (app_t app,
- gpg_error_t (*pincb)(void*, const char *, char **),
- void *pincb_arg)
+verify_a_chv (app_t app,
+ gpg_error_t (*pincb)(void*, const char *, char **),
+ void *pincb_arg,
+ int chvno, unsigned long sigcount, char **pinvalue)
{
int rc = 0;
+ char *prompt;
+ iso7816_pininfo_t pininfo;
+ int minlen = 6;
- if (!app->did_chv2)
+ assert (chvno == 1 || chvno == 2);
+
+ *pinvalue = NULL;
+
+ memset (&pininfo, 0, sizeof pininfo);
+ pininfo.mode = 1;
+ pininfo.minlen = minlen;
+
+ if (!opt.disable_keypad
+ && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
{
- char *pinvalue;
- iso7816_pininfo_t pininfo;
- int did_keypad = 0;
+ /* The reader supports the verify command through the keypad. */
- memset (&pininfo, 0, sizeof pininfo);
- pininfo.mode = 1;
- pininfo.minlen = 6;
+ if (chvno == 1)
+ {
+#define PROMPTSTRING _("||Please enter your PIN at the reader's keypad%%0A" \
+ "[sigs done: %lu]")
+ size_t promptsize = strlen (PROMPTSTRING) + 50;
- if (!opt.disable_keypad
- && !iso7816_check_keypad (app->slot, ISO7816_VERIFY, &pininfo) )
- {
- /* The reader supports the verify command through the keypad. */
- did_keypad = 1;
- rc = pincb (pincb_arg,
- _("||Please enter your PIN at the reader's keypad"),
- NULL);
- if (rc)
- {
- log_info (_("PIN callback returned error: %s\n"),
- gpg_strerror (rc));
- return rc;
- }
- rc = iso7816_verify_kp (app->slot, 0x82, "", 0, &pininfo);
- /* Dismiss the prompt. */
- pincb (pincb_arg, NULL, NULL);
+ prompt = xmalloc (promptsize);
+ if (!prompt)
+ return gpg_error_from_syserror ();
+ snprintf (prompt, promptsize-1, PROMPTSTRING, sigcount);
+ rc = pincb (pincb_arg, prompt, NULL);
+ xfree (prompt);
+#undef PROMPTSTRING
}
else
+ rc = pincb (pincb_arg,
+ _("||Please enter your PIN at the reader's keypad"),
+ NULL);
+ if (rc)
{
- /* The reader has no keypad or we don't want to use it. */
- rc = pincb (pincb_arg, "PIN", &pinvalue);
- if (rc)
- {
- log_info (_("PIN callback returned error: %s\n"),
- gpg_strerror (rc));
- return rc;
- }
-
- if (strlen (pinvalue) < 6)
- {
- log_error (_("PIN for CHV%d is too short;"
- " minimum length is %d\n"), 2, 6);
- xfree (pinvalue);
- return gpg_error (GPG_ERR_BAD_PIN);
- }
+ log_info (_("PIN callback returned error: %s\n"),
+ gpg_strerror (rc));
+ return rc;
+ }
+ rc = iso7816_verify_kp (app->slot, 0x80+chvno, "", 0, &pininfo);
+ /* Dismiss the prompt. */
+ pincb (pincb_arg, NULL, NULL);
- rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
+ assert (!*pinvalue);
+ }
+ else
+ {
+ /* The reader has no keypad or we don't want to use it. */
+
+ if (chvno == 1)
+ {
+#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]")
+ size_t promptsize = strlen (PROMPTSTRING) + 50;
+
+ prompt = xmalloc (promptsize);
+ if (!prompt)
+ return gpg_error_from_syserror ();
+ snprintf (prompt, promptsize-1, PROMPTSTRING, sigcount);
+ rc = pincb (pincb_arg, prompt, pinvalue);
+ xfree (prompt);
+#undef PROMPTSTRING
}
+ else
+ rc = pincb (pincb_arg, "PIN", pinvalue);
if (rc)
{
- log_error (_("verify CHV%d failed: %s\n"), 2, gpg_strerror (rc));
- xfree (pinvalue);
- flush_cache_after_error (app);
+ log_info (_("PIN callback returned error: %s\n"),
+ gpg_strerror (rc));
return rc;
}
- app->did_chv2 = 1;
+
+ if (strlen (*pinvalue) < minlen)
+ {
+ log_error (_("PIN for CHV%d is too short;"
+ " minimum length is %d\n"), chvno, minlen);
+ xfree (*pinvalue);
+ *pinvalue = NULL;
+ return gpg_error (GPG_ERR_BAD_PIN);
+ }
- if (!app->did_chv1 && !app->force_chv1 && !did_keypad)
+ rc = iso7816_verify (app->slot, 0x80+chvno,
+ *pinvalue, strlen (*pinvalue));
+ }
+
+ if (rc)
+ {
+ log_error (_("verify CHV%d failed: %s\n"), chvno, gpg_strerror (rc));
+ xfree (*pinvalue);
+ *pinvalue = NULL;
+ flush_cache_after_error (app);
+ }
+
+ return rc;
+}
+
+
+/* Verify CHV2 if required. Depending on the configuration of the
+ card CHV1 will also be verified. */
+static gpg_error_t
+verify_chv2 (app_t app,
+ gpg_error_t (*pincb)(void*, const char *, char **),
+ void *pincb_arg)
+{
+ int rc;
+ char *pinvalue;
+
+ if (app->did_chv2)
+ return 0; /* We already verified CHV2. */
+
+ rc = verify_a_chv (app, pincb, pincb_arg, 2, 0, &pinvalue);
+ if (rc)
+ return rc;
+
+ app->did_chv2 = 1;
+
+ if (!app->did_chv1 && !app->force_chv1 && pinvalue)
+ {
+ /* For convenience we verify CHV1 here too. We do this only if
+ the card is not configured to require a verification before
+ each CHV1 controlled operation (force_chv1) and if we are not
+ using the keypad (PINVALUE == NULL). */
+ rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
+ if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
+ rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
+ if (rc)
{
- rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
- if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
- rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
- if (rc)
- {
- log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc));
- xfree (pinvalue);
- flush_cache_after_error (app);
- return rc;
- }
- app->did_chv1 = 1;
+ log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc));
+ flush_cache_after_error (app);
}
- xfree (pinvalue);
+ else
+ app->did_chv1 = 1;
}
+ xfree (pinvalue);
+
return rc;
}
+
/* Verify CHV3 if required. */
static gpg_error_t
verify_chv3 (app_t app,
@@ -2076,6 +2146,7 @@
if (sha1fpr[i] != fpr[i])
{
xfree (buffer);
+ log_info (_("fingerprint on card does not match requested one\n"));
return gpg_error (GPG_ERR_WRONG_SECKEY);
}
xfree (buffer);
@@ -2230,44 +2301,16 @@
{
char *pinvalue;
- {
- char *prompt;
-#define PROMPTSTRING _("||Please enter the PIN%%0A[sigs done: %lu]")
-
- prompt = malloc (strlen (PROMPTSTRING) + 50);
- if (!prompt)
- return gpg_error_from_syserror ();
- sprintf (prompt, PROMPTSTRING, sigcount);
- rc = pincb (pincb_arg, prompt, &pinvalue);
- free (prompt);
-#undef PROMPTSTRING
- }
+ rc = verify_a_chv (app, pincb, pincb_arg, 1, sigcount, &pinvalue);
if (rc)
- {
- log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc));
- return rc;
- }
+ return rc;
- if (strlen (pinvalue) < 6)
- {
- log_error (_("PIN for CHV%d is too short;"
- " minimum length is %d\n"), 1, 6);
- xfree (pinvalue);
- return gpg_error (GPG_ERR_BAD_PIN);
- }
+ app->did_chv1 = 1;
- rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
- if (rc)
+ if (!app->did_chv2 && pinvalue)
{
- log_error (_("verify CHV%d failed: %s\n"), 1, gpg_strerror (rc));
- xfree (pinvalue);
- flush_cache_after_error (app);
- return rc;
- }
- app->did_chv1 = 1;
- if (!app->did_chv2)
- {
- /* We should also verify CHV2. */
+ /* We should also verify CHV2. Note, that we can't do that
+ if the keypad has been used. */
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
if (gpg_err_code (rc) == GPG_ERR_BAD_PIN)
rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED);
More information about the Gnupg-commits
mailing list