scd: Add option --clear to PASSWD.
authorWerner Koch <wk@gnupg.org>
Mon, 21 Jan 2019 13:06:51 +0000 (14:06 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 21 Jan 2019 13:06:51 +0000 (14:06 +0100)
* scd/command.c (cmd_passwd): Add option --clear.
(send_status_printf): New.
* scd/app-common.h (APP_CHANGE_FLAG_CLEAR): New.
* scd/app-nks.c (do_change_pin): Return an error if that option is
used.
* scd/app-openpgp.c (do_change_pin): Ditto.
--

Card application may support this option to clear the PIN verification
status of a specific PIN.

Signed-off-by: Werner Koch <wk@gnupg.org>
po/Makevars
scd/app-common.h
scd/app-nks.c
scd/app-openpgp.c
scd/app.c
scd/command.c
scd/scdaemon.h

index 90b0c5b..20d6ae9 100644 (file)
@@ -63,6 +63,7 @@ XGETTEXT_OPTIONS = \
        --flag=write_status_printf:2:c-format    \
        --flag=kbxd_print_status:3:c-format      \
        --flag=gpgconf_write_status:2:c-format   \
+        --flag=send_status_printf:3:c-format     \
        --flag=wks_write_status:2:c-format
 
 
index ff58318..b1661b5 100644 (file)
@@ -26,8 +26,9 @@
 #include <ksba.h>
 
 
-#define APP_CHANGE_FLAG_RESET    1
-#define APP_CHANGE_FLAG_NULLPIN  2
+#define APP_CHANGE_FLAG_RESET    1  /* PIN Reset mode.  */
+#define APP_CHANGE_FLAG_NULLPIN  2  /* NULL PIN mode.  */
+#define APP_CHANGE_FLAG_CLEAR    4  /* Clear the given PIN.  */
 
 /* Bit flags set by the decipher function into R_INFO.  */
 #define APP_DECIPHER_INFO_NOPAD  1  /* Padding has been removed.  */
index 801ab90..0f38e7c 100644 (file)
@@ -1169,6 +1169,9 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *pwidstr,
   if (!newdesc)
     return gpg_error (GPG_ERR_INV_ID);
 
+  if ((flags & APP_CHANGE_FLAG_CLEAR))
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   err = switch_application (app, is_sigg);
   if (err)
     return err;
index f25a360..fddc3b8 100644 (file)
@@ -2602,10 +2602,14 @@ do_change_pin (app_t app, ctrl_t ctrl,  const char *chvnostr,
   int pinlen = 0;
 
   (void)ctrl;
+
   memset (&pininfo, 0, sizeof pininfo);
   pininfo.fixedlen = -1;
   pininfo.minlen = minlen;
 
+  if ((flags & APP_CHANGE_FLAG_CLEAR))
+    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+
   if (reset_mode && chvno == 3)
     {
       rc = gpg_error (GPG_ERR_INV_ID);
index 800c954..8e09555 100644 (file)
--- a/scd/app.c
+++ b/scd/app.c
@@ -997,7 +997,7 @@ app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
 }
 
 
-/* Perform a VERIFY operation without doing anything lese.  This may
+/* Perform a VERIFY operation without doing anything else.  This may
    be used to initialize a the PIN cache for long lasting other
    operations.  Its use is highly application dependent. */
 gpg_error_t
index ea4ccbc..044831f 100644 (file)
@@ -1215,12 +1215,13 @@ cmd_random (assuan_context_t ctx, char *line)
 
 \f
 static const char hlp_passwd[] =
-  "PASSWD [--reset] [--nullpin] <chvno>\n"
+  "PASSWD [--reset] [--nullpin] [--clear] <chvno>\n"
   "\n"
   "Change the PIN or, if --reset is given, reset the retry counter of\n"
   "the card holder verification vector CHVNO.  The option --nullpin is\n"
-  "used for TCOS cards to set the initial PIN.  The format of CHVNO\n"
-  "depends on the card application.";
+  "used for TCOS cards to set the initial PIN.  The option --clear clears\n"
+  "the security status associated with the PIN so that the PIN needs to\n"
+  "be presented again. The format of CHVNO depends on the card application.";
 static gpg_error_t
 cmd_passwd (assuan_context_t ctx, char *line)
 {
@@ -1233,6 +1234,8 @@ cmd_passwd (assuan_context_t ctx, char *line)
     flags |= APP_CHANGE_FLAG_RESET;
   if (has_option (line, "--nullpin"))
     flags |= APP_CHANGE_FLAG_NULLPIN;
+  if (has_option (line, "--clear"))
+    flags |= APP_CHANGE_FLAG_CLEAR;
 
   line = skip_options (line);
 
@@ -1243,6 +1246,11 @@ cmd_passwd (assuan_context_t ctx, char *line)
     line++;
   *line = 0;
 
+  /* Do not allow other flags aside of --clear. */
+  if ((flags & APP_CHANGE_FLAG_CLEAR) && (flags & ~APP_CHANGE_FLAG_CLEAR))
+    return set_error (GPG_ERR_UNSUPPORTED_OPERATION,
+                      "--clear used with other options");
+
   if ((rc = open_card (ctrl)))
     return rc;
 
@@ -1922,6 +1930,26 @@ send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
 }
 
 
+/* This status functions expects a printf style format string.  No
+ * filtering of the data is done instead the orintf formatted data is
+ * send using assuan_send_status. */
+gpg_error_t
+send_status_printf (ctrl_t ctrl, const char *keyword, const char *format, ...)
+{
+  gpg_error_t err;
+  va_list arg_ptr;
+  assuan_context_t ctx;
+
+  if (!ctrl || !ctrl->server_local || !(ctx = ctrl->server_local->assuan_ctx))
+    return 0;
+
+  va_start (arg_ptr, format);
+  err = vprint_assuan_status (ctx, keyword, format, arg_ptr);
+  va_end (arg_ptr);
+  return err;
+}
+
+
 void
 popup_prompt (void *opaque, int on)
 {
index 238e6a8..73589ad 100644 (file)
@@ -123,6 +123,9 @@ int  scd_command_handler (ctrl_t, int);
 void send_status_info (ctrl_t ctrl, const char *keyword, ...)
      GPGRT_ATTR_SENTINEL(1);
 void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
+gpg_error_t send_status_printf (ctrl_t ctrl, const char *keyword,
+                                const char *format, ...) GPGRT_ATTR_PRINTF(3,4);
+
 void popup_prompt (void *opaque, int on);
 void send_client_notifications (app_t app, int removal);
 void scd_kick_the_loop (void);