[svn] GnuPG - r3947 - in branches/GNUPG-1-9-BRANCH: . agent am kbx
po scd tools
svn author wk
cvs at cvs.gnupg.org
Mon Nov 28 12:52:28 CET 2005
Author: wk
Date: 2005-11-28 12:52:25 +0100 (Mon, 28 Nov 2005)
New Revision: 3947
Modified:
branches/GNUPG-1-9-BRANCH/ChangeLog
branches/GNUPG-1-9-BRANCH/NEWS
branches/GNUPG-1-9-BRANCH/TODO
branches/GNUPG-1-9-BRANCH/agent/ChangeLog
branches/GNUPG-1-9-BRANCH/agent/agent.h
branches/GNUPG-1-9-BRANCH/agent/call-scd.c
branches/GNUPG-1-9-BRANCH/agent/command.c
branches/GNUPG-1-9-BRANCH/agent/divert-scd.c
branches/GNUPG-1-9-BRANCH/agent/minip12.c
branches/GNUPG-1-9-BRANCH/agent/query.c
branches/GNUPG-1-9-BRANCH/agent/t-protect.c
branches/GNUPG-1-9-BRANCH/am/cmacros.am
branches/GNUPG-1-9-BRANCH/configure.ac
branches/GNUPG-1-9-BRANCH/kbx/keybox-blob.c
branches/GNUPG-1-9-BRANCH/po/POTFILES.in
branches/GNUPG-1-9-BRANCH/po/de.po
branches/GNUPG-1-9-BRANCH/scd/ChangeLog
branches/GNUPG-1-9-BRANCH/scd/apdu.c
branches/GNUPG-1-9-BRANCH/scd/apdu.h
branches/GNUPG-1-9-BRANCH/scd/app-dinsig.c
branches/GNUPG-1-9-BRANCH/scd/app-nks.c
branches/GNUPG-1-9-BRANCH/scd/app-openpgp.c
branches/GNUPG-1-9-BRANCH/scd/app-p15.c
branches/GNUPG-1-9-BRANCH/scd/ccid-driver.c
branches/GNUPG-1-9-BRANCH/scd/ccid-driver.h
branches/GNUPG-1-9-BRANCH/scd/iso7816.c
branches/GNUPG-1-9-BRANCH/scd/iso7816.h
branches/GNUPG-1-9-BRANCH/scd/scdaemon.c
branches/GNUPG-1-9-BRANCH/scd/scdaemon.h
branches/GNUPG-1-9-BRANCH/tools/ChangeLog
branches/GNUPG-1-9-BRANCH/tools/gpgconf-comp.c
branches/GNUPG-1-9-BRANCH/tools/rfc822parse.c
Log:
Preparing an interim release
Modified: branches/GNUPG-1-9-BRANCH/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/ChangeLog 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/ChangeLog 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,3 +1,19 @@
+2005-11-28 Werner Koch <wk at g10code.com>
+
+ * configure.ac: Append the revision to the version string.
+
+2005-11-13 Werner Koch <wk at g10code.com>
+
+ * am/cmacros.am (-DGNUPG_SYSCONFDIR): Define it.
+
+2005-11-11 Werner Koch <wk at g10code.com>
+
+ * configure.ac (NEED_KSBA_VERSION: Require 0.9.13.
+
+2005-09-12 Werner Koch <wk at g10code.com>
+
+ Released 1.9.19.
+
2005-08-01 Werner Koch <wk at g10code.com>
Released 1.9.18.
Modified: branches/GNUPG-1-9-BRANCH/NEWS
===================================================================
--- branches/GNUPG-1-9-BRANCH/NEWS 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/NEWS 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,3 +1,10 @@
+Noteworthy changes in version 1.9.20
+-------------------------------------------------
+
+ * [scdaemon] Support for keypads of some readers. Tested only with
+ SPR532. New option --disable-keypad.
+
+
Noteworthy changes in version 1.9.19 (2005-09-12)
-------------------------------------------------
Modified: branches/GNUPG-1-9-BRANCH/TODO
===================================================================
--- branches/GNUPG-1-9-BRANCH/TODO 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/TODO 2005-11-28 11:52:25 UTC (rev 3947)
@@ -26,7 +26,6 @@
* sm/gpgsm.c
** Support --output for all commands
** mark all unimplemented commands and options.
-** Print a hint when MD2 is the cause for a problem.
** Implement --default-key
** support the anyPolicy semantic
** Check that we are really following the verification procedures in rfc3280.
Modified: branches/GNUPG-1-9-BRANCH/agent/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/ChangeLog 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/ChangeLog 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,3 +1,20 @@
+2005-11-24 Werner Koch <wk at g10code.com>
+
+ * minip12.c (p12_parse): Fixed for case that the key object comes
+ prior to the certificate.
+
+2005-10-19 Werner Koch <wk at g10code.com>
+
+ * divert-scd.c (getpin_cb): Hack to use it for a keypad message.
+
+ * call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO.
+
+ * query.c (start_pinentry): Keep track of the owner.
+ (popup_message_thread, agent_popup_message_start)
+ (agent_popup_message_stop, agent_reset_query): New.
+ * command.c (start_command_handler): Make sure a popup window gets
+ closed.
+
2005-10-08 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (gpg_protect_tool_LDADD): Add ../gl/libgnu.a.
Modified: branches/GNUPG-1-9-BRANCH/agent/agent.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/agent.h 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/agent.h 2005-11-28 11:52:25 UTC (rev 3947)
@@ -133,7 +133,7 @@
int have_keygrip;
int use_auth_call; /* Hack to send the PKAUTH command instead of the
- PKSIGN command tro scdaemon. */
+ PKSIGN command to the scdaemon. */
};
typedef struct server_control_s *CTRL;
typedef struct server_control_s *ctrl_t;
@@ -200,6 +200,7 @@
/*-- query.c --*/
void initialize_module_query (void);
void agent_query_dump_state (void);
+void agent_reset_query (ctrl_t ctrl);
int agent_askpin (ctrl_t ctrl,
const char *desc_text, const char *prompt_text,
const char *inital_errtext,
@@ -209,7 +210,11 @@
const char *errtext);
int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
const char *cancel);
+int agent_popup_message_start (ctrl_t ctrl, const char *desc,
+ const char *ok_btn, const char *cancel_btn);
+void agent_popup_message_stop (ctrl_t ctrl);
+
/*-- cache.c --*/
void agent_flush_cache (void);
int agent_put_cache (const char *key, cache_mode_t cache_mode,
Modified: branches/GNUPG-1-9-BRANCH/agent/call-scd.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/call-scd.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/call-scd.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -633,27 +633,44 @@
size_t pinlen;
int rc;
- if (!(!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7])))
+ if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
{
+ line += 7;
+ while (*line == ' ')
+ line++;
+
+ pinlen = 90;
+ pin = gcry_malloc_secure (pinlen);
+ if (!pin)
+ return ASSUAN_Out_Of_Core;
+
+ rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
+ if (rc)
+ rc = ASSUAN_Canceled;
+ if (!rc)
+ rc = assuan_send_data (parm->ctx, pin, pinlen);
+ xfree (pin);
+ }
+ else if (!strncmp (line, "KEYPADINFO", 10) && (line[10] == ' ' || !line[10]))
+ {
+ size_t code;
+ char *endp;
+
+ code = strtoul (line+10, &endp, 10);
+ line = endp;
+ while (*line == ' ')
+ line++;
+
+ rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, code);
+ if (rc)
+ rc = ASSUAN_Canceled;
+ }
+ else
+ {
log_error ("unsupported inquiry `%s'\n", line);
- return ASSUAN_Inquire_Unknown;
+ rc = ASSUAN_Inquire_Unknown;
}
- line += 7;
- while (*line == ' ')
- line++;
- pinlen = 90;
- pin = gcry_malloc_secure (pinlen);
- if (!pin)
- return ASSUAN_Out_Of_Core;
-
- rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
- if (rc)
- rc = ASSUAN_Canceled;
- if (!rc)
- rc = assuan_send_data (parm->ctx, pin, pinlen);
- xfree (pin);
-
return rc;
}
Modified: branches/GNUPG-1-9-BRANCH/agent/command.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/command.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/command.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -316,11 +316,11 @@
this command is not used a default text will be used. Note, that
this description implictly selects the label used for the entry
box; if the string contains the string PIN (which in general will
- not be translated), "PIN" is used, other wiese the translation of
+ not be translated), "PIN" is used, otherwise the translation of
'passphrase" is used. The description string should not contain
blanks unless they are percent or '+' escaped.
- The descrition is only valid for the next PKSIGN or PKDECRYPT
+ The description is only valid for the next PKSIGN or PKDECRYPT
operation.
*/
static int
@@ -399,7 +399,7 @@
/* PKSIGN <options>
Perform the actual sign operation. Neither input nor output are
- sensitive to eavesdropping */
+ sensitive to eavesdropping. */
static int
cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
{
@@ -1085,6 +1085,9 @@
/* Reset the SCD if needed. */
agent_reset_scd (&ctrl);
+ /* Reset the pinentry (in case of popup messages). */
+ agent_reset_query (&ctrl);
+
assuan_deinit_server (ctx);
if (ctrl.display)
free (ctrl.display);
Modified: branches/GNUPG-1-9-BRANCH/agent/divert-scd.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/divert-scd.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/divert-scd.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -204,7 +204,7 @@
const char *again_text = NULL;
const char *prompt = "PIN";
- if (maxbuf < 2)
+ if (buf && maxbuf < 2)
return gpg_error (GPG_ERR_INV_VALUE);
/* Parse the flags. */
@@ -223,6 +223,23 @@
else if (info && *info == '|')
log_debug ("pin_cb called without proper PIN info hack\n");
+ /* If BUF has been passed as NULL, we are in keypad mode: The
+ callback opens the popup and immediatley returns. */
+ if (!buf)
+ {
+ if (maxbuf == 0) /* Close the pinentry. */
+ {
+ agent_popup_message_stop (ctrl);
+ rc = 0;
+ }
+ else if (maxbuf == 1) /* Open the pinentry. */
+ {
+ rc = agent_popup_message_start (ctrl, info, NULL, NULL);
+ }
+ else
+ rc = gpg_error (GPG_ERR_INV_VALUE);
+ return rc;
+ }
/* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole
mess because we should call the card's verify function from the
Modified: branches/GNUPG-1-9-BRANCH/agent/minip12.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/minip12.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/minip12.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -511,7 +511,7 @@
goto bailout;
}
- /* Loop over all certificates inside the bab. */
+ /* Loop over all certificates inside the bag. */
while (n)
{
int isbag = 0;
@@ -860,6 +860,7 @@
size_t n = length;
const char *where;
int bagseqlength, len;
+ gcry_mpi_t *result = NULL;
where = "pfx";
if (parse_tag (&p, &n, &ti))
@@ -936,10 +937,17 @@
else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data)
&& !memcmp (p, oid_data, DIM(oid_data)))
{
- p += DIM(oid_data);
- n -= DIM(oid_data);
- len -= DIM(oid_data);
- return parse_bag_data (p, n, (p-buffer), pw);
+ if (result)
+ log_info ("already got an data object, skipping next one\n");
+ else
+ {
+ p += DIM(oid_data);
+ n -= DIM(oid_data);
+ len -= DIM(oid_data);
+ result = parse_bag_data (p, n, (p-buffer), pw);
+ if (!result)
+ goto bailout;
+ }
}
else
log_info ( "unknown bag type - skipped\n");
@@ -950,9 +958,10 @@
n -= len;
}
- return NULL;
+ return result;
bailout:
log_error ("error at \"%s\", offset %u\n", where, (p - buffer));
+ /* fixme: need to release RESULT. */
return NULL;
}
Modified: branches/GNUPG-1-9-BRANCH/agent/query.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/query.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/query.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -27,9 +27,10 @@
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
-#ifdef USE_GNU_PTH
-# include <pth.h>
+#ifndef HAVE_W32_SYSTEM
+#include <sys/wait.h>
#endif
+#include <pth.h>
#include "agent.h"
#include "i18n.h"
@@ -48,14 +49,30 @@
time. */
#define LOCK_TIMEOUT (1*60)
+/* The assuan context of the current pinentry. */
+static assuan_context_t entry_ctx;
-static assuan_context_t entry_ctx = NULL;
-#ifdef USE_GNU_PTH
+/* The control variable of the connection owning the current pinentry.
+ This is only valid if ENTRY_CTX is not NULL. Note, that we care
+ only about the value of the pointer and that it should never be
+ dereferenced. */
+static ctrl_t entry_owner;
+
+/* A mutex used to serialize access to the pinentry. */
static pth_mutex_t entry_lock;
-#endif
-/* data to be passed to our callbacks */
-struct entry_parm_s {
+/* The thread ID of the popup working thread. */
+static pth_t popup_tid;
+
+/* A flag used in communication between the popup working thread and
+ its stop function. */
+static int popup_finished;
+
+
+
+/* Data to be passed to our callbacks, */
+struct entry_parm_s
+{
int lines;
size_t size;
unsigned char *buffer;
@@ -67,17 +84,17 @@
/* This function must be called once to initialize this module. This
has to be done before a second thread is spawned. We can't do the
static initialization because Pth emulation code might not be able
- to do a static init; in particualr, it is not possible for W32. */
+ to do a static init; in particular, it is not possible for W32. */
void
initialize_module_query (void)
{
-#ifdef USE_GNU_PTH
static int initialized;
if (!initialized)
- if (pth_mutex_init (&entry_lock))
- initialized = 1;
-#endif /*USE_GNU_PTH*/
+ {
+ if (pth_mutex_init (&entry_lock))
+ initialized = 1;
+ }
}
@@ -102,11 +119,22 @@
log_info ("agent_query_dump_state: entry_lock=");
dump_mutex_state (&entry_lock);
log_printf ("\n");
- log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld\n",
- entry_ctx, (long)assuan_get_pid (entry_ctx));
+ log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
+ entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
}
+/* Called to make sure that a popup window owned by the current
+ connection gets closed. */
+void
+agent_reset_query (ctrl_t ctrl)
+{
+ if (entry_ctx && popup_tid && entry_owner == ctrl)
+ {
+ agent_popup_message_stop (ctrl);
+ }
+}
+
/* Unlock the pinentry so that another thread can start one and
disconnect that pinentry - we do this after the unlock so that a
stalled pinentry does not block other threads. Fixme: We should
@@ -117,14 +145,12 @@
assuan_context_t ctx = entry_ctx;
entry_ctx = NULL;
-#ifdef USE_GNU_PTH
if (!pth_mutex_release (&entry_lock))
{
log_error ("failed to release the entry lock\n");
if (!rc)
rc = gpg_error (GPG_ERR_INTERNAL);
}
-#endif
assuan_disconnect (ctx);
return rc;
}
@@ -145,7 +171,7 @@
pinentry - we will serialize _all_ pinentry calls.
*/
static int
-start_pinentry (CTRL ctrl)
+start_pinentry (ctrl_t ctrl)
{
int rc;
const char *pgmname;
@@ -153,13 +179,10 @@
const char *argv[5];
int no_close_list[3];
int i;
+ pth_event_t evt;
-#ifdef USE_GNU_PTH
- {
- pth_event_t evt;
-
- evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
- if (!pth_mutex_acquire (&entry_lock, 0, evt))
+ evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
+ if (!pth_mutex_acquire (&entry_lock, 0, evt))
{
if (pth_event_occurred (evt))
rc = gpg_error (GPG_ERR_TIMEOUT);
@@ -170,10 +193,10 @@
gpg_strerror (rc));
return rc;
}
- pth_event_free (evt, PTH_FREE_THIS);
- }
-#endif
+ pth_event_free (evt, PTH_FREE_THIS);
+ entry_owner = ctrl;
+
if (entry_ctx)
return 0;
@@ -436,7 +459,7 @@
passphrase is returned in RETPASS as an hex encoded string to be
freed by the caller */
int
-agent_get_passphrase (CTRL ctrl,
+agent_get_passphrase (ctrl_t ctrl,
char **retpass, const char *desc, const char *prompt,
const char *errtext)
{
@@ -517,11 +540,11 @@
/* Pop up the PIN-entry, display the text and the prompt and ask the
- user to confirm this. We return 0 for success, ie. the used
+ user to confirm this. We return 0 for success, ie. the user
confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
other error. */
int
-agent_get_confirmation (CTRL ctrl,
+agent_get_confirmation (ctrl_t ctrl,
const char *desc, const char *ok, const char *cancel)
{
int rc;
@@ -562,4 +585,119 @@
}
+/* The thread running the popup message. */
+static void *
+popup_message_thread (void *arg)
+{
+ assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL);
+ popup_finished = 1;
+ return NULL;
+}
+
+/* Pop up a message window similar to the confirm one but keep it open
+ until agent_popup_message_stop has been called. It is crucial for
+ the caller to make sure that the stop function gets called as soon
+ as the message is not anymore required becuase the message is
+ system modal and all other attempts to use the pinentry will fail
+ (after a timeout). */
+int
+agent_popup_message_start (ctrl_t ctrl, const char *desc,
+ const char *ok_btn, const char *cancel_btn)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ pth_attr_t tattr;
+
+ rc = start_pinentry (ctrl);
+ if (rc)
+ return rc;
+
+ if (desc)
+ snprintf (line, DIM(line)-1, "SETDESC %s", desc);
+ else
+ snprintf (line, DIM(line)-1, "RESET");
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc)
+ return unlock_pinentry (map_assuan_err (rc));
+
+ if (ok_btn)
+ {
+ snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
+ if (rc)
+ return unlock_pinentry (map_assuan_err (rc));
+ }
+ if (cancel_btn)
+ {
+ snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel_btn);
+ line[DIM(line)-1] = 0;
+ rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL);
+ if (rc)
+ return unlock_pinentry (map_assuan_err (rc));
+ }
+
+ tattr = pth_attr_new();
+ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
+ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
+ pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message");
+
+ popup_finished = 0;
+ popup_tid = pth_spawn (tattr, popup_message_thread, NULL);
+ if (!popup_tid)
+ {
+ rc = gpg_error_from_errno (errno);
+ log_error ("error spawning popup message handler: %s\n",
+ strerror (errno) );
+ pth_attr_destroy (tattr);
+ return unlock_pinentry (rc);
+ }
+ pth_attr_destroy (tattr);
+
+ return 0;
+}
+
+/* Close a popup window. */
+void
+agent_popup_message_stop (ctrl_t ctrl)
+{
+ int rc;
+ pid_t pid;
+
+ if (!popup_tid || !entry_ctx)
+ {
+ log_debug ("agent_popup_message_stop called with no active popup\n");
+ return;
+ }
+
+ pid = assuan_get_pid (entry_ctx);
+ if (pid == (pid_t)(-1))
+ ; /* No pid available can't send a kill. */
+ else if (popup_finished)
+ ; /* Already finished and ready for joining. */
+ else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
+ { /* The daemon already died. No need to send a kill. However
+ because we already waited for the process, we need to tell
+ assuan that it should not wait again (done by
+ unlock_pinentry). */
+ if (rc == pid)
+ assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
+ }
+ else
+ kill (pid, SIGINT);
+
+ /* Now wait for the thread to terminate. */
+ rc = pth_join (popup_tid, NULL);
+ if (!rc)
+ log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
+ strerror (errno));
+ popup_tid = NULL;
+ entry_owner = NULL;
+
+ /* Now we can close the connection. */
+ unlock_pinentry (0);
+}
+
+
Modified: branches/GNUPG-1-9-BRANCH/agent/t-protect.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/agent/t-protect.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/agent/t-protect.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -173,7 +173,8 @@
for (i = 0; i < DIM (specs); i++)
{
- ret = agent_protect (specs[i].key, specs[i].passphrase,
+ ret = agent_protect ((const unsigned char*)specs[i].key,
+ specs[i].passphrase,
&specs[i].result, &specs[i].resultlen);
if (gpg_err_code (ret) != specs[i].ret_expected)
{
Modified: branches/GNUPG-1-9-BRANCH/am/cmacros.am
===================================================================
--- branches/GNUPG-1-9-BRANCH/am/cmacros.am 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/am/cmacros.am 2005-11-28 11:52:25 UTC (rev 3947)
@@ -25,7 +25,8 @@
AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \
-DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \
-DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \
- -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\""
+ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \
+ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\""
endif
if GNUPG_AGENT_PGM
Modified: branches/GNUPG-1-9-BRANCH/configure.ac
===================================================================
--- branches/GNUPG-1-9-BRANCH/configure.ac 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/configure.ac 2005-11-28 11:52:25 UTC (rev 3947)
@@ -22,9 +22,12 @@
AC_PREREQ(2.52)
min_automake_version="1.9.3"
-# Version number: Remember to change it immediately *after* a release.
-# Add a "-cvs" prefix for non-released code.
-AC_INIT(gnupg, 1.9.19, gnupg-devel at gnupg.org)
+# Remember to change the version number immediately *after* a release.
+# Uncomment the my_iscvs macro for non-released code.
+m4_define(my_version, [1.9.20])
+m4_define(my_iscvs, yes)
+AC_INIT([gnupg], my_version[]m4_ifdef([my_iscvs], [-cvs[]m4_translit(
+ [$Revision$],[Ra-z $:])]), [gnupg-devel at gnupg.org])
# Set development_version to yes if the minor number is odd or you
# feel that the default check for a development version is not
# sufficient.
@@ -36,7 +39,7 @@
NEED_LIBASSUAN_VERSION=0.6.10
-NEED_KSBA_VERSION=0.9.12
+NEED_KSBA_VERSION=0.9.13
PACKAGE=$PACKAGE_NAME
Modified: branches/GNUPG-1-9-BRANCH/kbx/keybox-blob.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/kbx/keybox-blob.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/kbx/keybox-blob.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -61,7 +61,7 @@
u32 offset to the n-th key's keyID (a keyID is always 8 byte)
or 0 if not known which is the case only for X509.
u16 special key flags
- bit 0 =
+ bit 0 = qualified signature (not yet implemented}
u16 reserved
u16 size of serialnumber(may be zero)
n u16 (see above) bytes of serial number
Modified: branches/GNUPG-1-9-BRANCH/po/POTFILES.in
===================================================================
--- branches/GNUPG-1-9-BRANCH/po/POTFILES.in 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/po/POTFILES.in 2005-11-28 11:52:25 UTC (rev 3947)
@@ -17,6 +17,7 @@
scd/scdaemon.c
scd/app-openpgp.c
+scd/app-nks.c
sm/base64.c
sm/call-agent.c
Modified: branches/GNUPG-1-9-BRANCH/po/de.po
===================================================================
--- branches/GNUPG-1-9-BRANCH/po/de.po 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/po/de.po 2005-11-28 11:52:25 UTC (rev 3947)
@@ -10,8 +10,8 @@
msgstr ""
"Project-Id-Version: gnupg2 1.9.18\n"
"Report-Msgid-Bugs-To: translations at gnupg.org\n"
-"POT-Creation-Date: 2005-11-23 13:00+0100\n"
-"PO-Revision-Date: 2005-11-23 13:02+0100\n"
+"POT-Creation-Date: 2005-11-28 12:14+0100\n"
+"PO-Revision-Date: 2005-11-28 12:16+0100\n"
"Last-Translator: Werner Koch <wk at gnupg.org>\n"
"Language-Team: de\n"
"MIME-Version: 1.0\n"
@@ -766,6 +766,10 @@
msgid "can't access %s - invalid OpenPGP card?\n"
msgstr "Zugriff auf %s nicht möglich - ungültige OpenPGP Karte?\n"
+#: scd/app-nks.c:344
+msgid "the NullPIN has not yet been changed\n"
+msgstr "Die Nullpin wurde noch nicht geändert\n"
+
#: sm/base64.c:317
#, c-format
msgid "invalid radix64 character %02x skipped\n"
@@ -1369,7 +1373,7 @@
#: sm/gpgsm.c:1475
msgid "this command has not yet been implemented\n"
-msgstr "Diee Kommando wurde noch nicht implementiert\n"
+msgstr "Dieses Kommando wurde noch nicht implementiert\n"
#: sm/gpgsm.c:1705 sm/gpgsm.c:1742 sm/qualified.c:73
#, c-format
@@ -1548,10 +1552,10 @@
msgstr ""
"Sie sind dabei, eine Signatur mit dem Zertifikat:\n"
"\"%s\"\n"
-"zu erzeugen. Dies wird einen qualifizierte Signatur erzeugen, \n"
-"die gesetzlich einer handgeschriebene gleichgestellt ist.\n"
+"zu erzeugen. Dies wird eine qualifizierte Signatur erzeugen, \n"
+"die gesetzlich einer handgeschriebenen gleichgestellt ist.\n"
"\n"
-"%s%sSind Sie wirklich sicher, da Sie dies möchten?"
+"%s%sSind Sie wirklich sicher, daß Sie dies möchten?"
#: sm/qualified.c:224
msgid ""
Modified: branches/GNUPG-1-9-BRANCH/scd/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/ChangeLog 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/ChangeLog 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,3 +1,46 @@
+2005-11-23 Werner Koch <wk at g10code.com>
+
+ * app-nks.c (verify_pin): Give a special error message for a Nullpin.
+
+2005-10-29 Werner Koch <wk at g10code.com>
+
+ * ccid-driver.c (send_escape_cmd): New args RESULT, RESULTLEN and
+ RESULTMAX. Changed all callers.
+ (ccid_transceive_escape): New.
+
+2005-10-27 Werner Koch <wk at g10code.com>
+
+ * apdu.c [__CYGWIN__]: Make cygwin environment similar to _WIN32.
+ Suggested by John P. Clizbe.
+ * scdaemon.c [__CYGWIN__]: Set default PC/SC driver to winscard.dll.
+
+2005-10-19 Werner Koch <wk at g10code.com>
+
+ * ccid-driver.h (CCID_DRIVER_ERR_NO_KEYPAD): New.
+ * apdu.h (SW_HOST_NO_KEYPAD): New.
+ * iso7816.h (struct iso7816_pininfo_s): New.
+ * iso7816.c (map_sw): Support new code.
+ (iso7816_check_keypad): New.
+ (iso7816_verify_kp, iso7816_change_reference_data_kp)
+ (iso7816_reset_retry_counter_kp): New. Extended versions of the
+ original functions.
+ * apdu.c (host_sw_string): Support new code.
+ (reader_table_s): New field CHECK_KEYPAD.
+ (new_reader_slot, open_ct_reader, open_pcsc_reader)
+ (open_ccid_reader, open_rapdu_reader): Initialize it.
+ (check_ccid_keypad): New.
+ (apdu_check_keypad): New.
+ (apdu_send_le): Factored all code out to ...
+ (send_le): .. new. Takes an additional arg; changed all callers
+ of the orginal function to use this one with a NULL for the new
+ arg.
+ (apdu_send_simple_kp): New.
+ (ct_send_apdu, pcsc_send_apdu, my_rapdu_send_apdu)
+ (send_apdu_ccid): New arg PININFO.
+ (send_apdu_ccid): Use the new arg.
+
+ * scdaemon.c: New option --disable-keypad.
+
2005-10-08 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (scdaemon_LDADD): Add ../gl/libgnu.a after
@@ -3,4 +46,16 @@
../common/libcommon.a.
+2005-09-20 Werner Koch <wk at g10code.com>
+
+ * app-dinsig.c (verify_pin): Try ISO 9564 BCD encoding.
+
+ * iso7816.c (iso7816_select_application): Add arg FLAGS. Changed
+ all callers to pass 0.
+ * app-openpgp.c (app_select_openpgp): But this one requires a
+ special flag.
+
+ * app-p15.c (app_select_p15): Don't use select application for the
+ BELPIC.
+
2005-09-09 Werner Koch <wk at g10code.com>
Modified: branches/GNUPG-1-9-BRANCH/scd/apdu.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/apdu.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/apdu.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -66,10 +66,10 @@
#include "ccid-driver.h"
-/* To to conflicting use of threading libraries we usually can't link
+/* Due to conflicting use of threading libraries we usually can't link
against libpcsclite. Instead we use a wrapper program. */
#ifdef USE_GNU_PTH
-#ifndef HAVE_W32_SYSTEM
+#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__)
#define NEED_PCSC_WRAPPER 1
#endif
#endif
@@ -78,7 +78,7 @@
#define MAX_READER 4 /* Number of readers we support concurrently. */
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
#define DLSTDCALL __stdcall
#else
#define DLSTDCALL
@@ -90,6 +90,14 @@
#define MAX_OPEN_FDS 20
#endif
+/* Helper to pass patrameters related to keypad based operations. */
+struct pininfo_s
+{
+ int mode;
+ int minlen;
+ int maxlen;
+ int padlen;
+};
/* A structure to collect information pertaining to one reader
slot. */
@@ -103,7 +111,8 @@
int (*reset_reader)(int);
int (*get_status_reader)(int, unsigned int *);
int (*send_apdu_reader)(int,unsigned char *,size_t,
- unsigned char *, size_t *);
+ unsigned char *, size_t *, struct pininfo_s *);
+ int (*check_keypad)(int, int, int, int, int, int);
void (*dump_status_reader)(int);
struct {
@@ -320,6 +329,7 @@
reader_table[reader].reset_reader = NULL;
reader_table[reader].get_status_reader = NULL;
reader_table[reader].send_apdu_reader = NULL;
+ reader_table[reader].check_keypad = NULL;
reader_table[reader].dump_status_reader = NULL;
reader_table[reader].used = 1;
@@ -372,6 +382,7 @@
case SW_HOST_GENERAL_ERROR: return "general error";
case SW_HOST_NO_READER: return "no reader";
case SW_HOST_ABORTED: return "aborted";
+ case SW_HOST_NO_KEYPAD: return "no keypad";
default: return "unknown host status error";
}
}
@@ -533,7 +544,7 @@
set to BUFLEN. Returns: CT API error code. */
static int
ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
- unsigned char *buffer, size_t *buflen)
+ unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
{
int rc;
unsigned char dad[1], sad[1];
@@ -596,6 +607,7 @@
reader_table[reader].reset_reader = reset_ct_reader;
reader_table[reader].get_status_reader = ct_get_status;
reader_table[reader].send_apdu_reader = ct_send_apdu;
+ reader_table[reader].check_keypad = NULL;
reader_table[reader].dump_status_reader = ct_dump_reader_status;
dump_reader_status (reader);
@@ -1082,7 +1094,8 @@
set to BUFLEN. Returns: CT API error code. */
static int
pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
- unsigned char *buffer, size_t *buflen)
+ unsigned char *buffer, size_t *buflen,
+ struct pininfo_s *pininfo)
{
#ifdef NEED_PCSC_WRAPPER
long err;
@@ -1479,6 +1492,7 @@
reader_table[slot].reset_reader = reset_pcsc_reader;
reader_table[slot].get_status_reader = pcsc_get_status;
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
+ reader_table[slot].check_keypad = NULL;
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
/* Read the status so that IS_T0 will be set. */
@@ -1625,6 +1639,7 @@
reader_table[slot].reset_reader = reset_pcsc_reader;
reader_table[slot].get_status_reader = pcsc_get_status;
reader_table[slot].send_apdu_reader = pcsc_send_apdu;
+ reader_table[slot].check_keypad = NULL;
reader_table[slot].dump_status_reader = dump_pcsc_reader_status;
/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */
@@ -1713,7 +1728,8 @@
set to BUFLEN. Returns: Internal CCID driver error code. */
static int
send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen,
- unsigned char *buffer, size_t *buflen)
+ unsigned char *buffer, size_t *buflen,
+ struct pininfo_s *pininfo)
{
long err;
size_t maxbuflen;
@@ -1727,9 +1743,18 @@
log_printhex (" APDU_data:", apdu, apdulen);
maxbuflen = *buflen;
- err = ccid_transceive (reader_table[slot].ccid.handle,
- apdu, apdulen,
- buffer, maxbuflen, buflen);
+ if (pininfo)
+ err = ccid_transceive_secure (reader_table[slot].ccid.handle,
+ apdu, apdulen,
+ pininfo->mode,
+ pininfo->minlen,
+ pininfo->maxlen,
+ pininfo->padlen,
+ buffer, maxbuflen, buflen);
+ else
+ err = ccid_transceive (reader_table[slot].ccid.handle,
+ apdu, apdulen,
+ buffer, maxbuflen, buflen);
if (err)
log_error ("ccid_transceive failed: (0x%lx)\n",
err);
@@ -1737,6 +1762,24 @@
return err;
}
+
+/* Check whether the CCID reader supports the ISO command code COMMAND
+ on the keypad. Return 0 on success. For a description of the pin
+ parameters, see ccid-driver.c */
+static int
+check_ccid_keypad (int slot, int command, int pin_mode,
+ int pinlen_min, int pinlen_max, int pin_padlen)
+{
+ unsigned char apdu[] = { 0, 0, 0, 0x81 };
+
+ apdu[1] = command;
+ return ccid_transceive_secure (reader_table[slot].ccid.handle,
+ apdu, sizeof apdu,
+ pin_mode, pinlen_min, pinlen_max, pin_padlen,
+ NULL, 0, NULL);
+}
+
+
/* Open the reader and try to read an ATR. */
static int
open_ccid_reader (const char *portstr)
@@ -1776,6 +1819,7 @@
reader_table[slot].reset_reader = reset_ccid_reader;
reader_table[slot].get_status_reader = get_status_ccid;
reader_table[slot].send_apdu_reader = send_apdu_ccid;
+ reader_table[slot].check_keypad = check_ccid_keypad;
reader_table[slot].dump_status_reader = dump_ccid_reader_status;
dump_reader_status (slot);
@@ -1932,7 +1976,8 @@
set to BUFLEN. Returns: APDU error code. */
static int
my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
- unsigned char *buffer, size_t *buflen)
+ unsigned char *buffer, size_t *buflen,
+ struct pininfo_s *pininfo)
{
int err;
reader_table_t slotp;
@@ -2063,6 +2108,7 @@
reader_table[slot].reset_reader = reset_rapdu_reader;
reader_table[slot].get_status_reader = my_rapdu_get_status;
reader_table[slot].send_apdu_reader = my_rapdu_send_apdu;
+ reader_table[slot].check_keypad = NULL;
reader_table[slot].dump_status_reader = NULL;
dump_reader_status (slot);
@@ -2198,28 +2244,28 @@
pcsc_establish_context = dlsym (handle, "SCardEstablishContext");
pcsc_release_context = dlsym (handle, "SCardReleaseContext");
pcsc_list_readers = dlsym (handle, "SCardListReaders");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_list_readers)
pcsc_list_readers = dlsym (handle, "SCardListReadersA");
#endif
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_get_status_change)
pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA");
#endif
pcsc_connect = dlsym (handle, "SCardConnect");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_connect)
pcsc_connect = dlsym (handle, "SCardConnectA");
#endif
pcsc_reconnect = dlsym (handle, "SCardReconnect");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_reconnect)
pcsc_reconnect = dlsym (handle, "SCardReconnectA");
#endif
pcsc_disconnect = dlsym (handle, "SCardDisconnect");
pcsc_status = dlsym (handle, "SCardStatus");
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
if (!pcsc_status)
pcsc_status = dlsym (handle, "SCardStatusA");
#endif
@@ -2492,11 +2538,30 @@
}
+/* Check whether the reader supports the ISO command code COMMAND on
+ the keypad. Return 0 on success. For a description of the pin
+ parameters, see ccid-driver.c */
+int
+apdu_check_keypad (int slot, int command, int pin_mode,
+ int pinlen_min, int pinlen_max, int pin_padlen)
+{
+ if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+ return SW_HOST_NO_DRIVER;
+
+ if (reader_table[slot].check_keypad)
+ return reader_table[slot].check_keypad (slot, command,
+ pin_mode, pinlen_min, pinlen_max,
+ pin_padlen);
+ else
+ return SW_HOST_NOT_SUPPORTED;
+}
+
+
/* Dispatcher for the actual send_apdu function. Note, that this
function should be called in locked state. */
static int
send_apdu (int slot, unsigned char *apdu, size_t apdulen,
- unsigned char *buffer, size_t *buflen)
+ unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo)
{
if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
return SW_HOST_NO_DRIVER;
@@ -2504,24 +2569,20 @@
if (reader_table[slot].send_apdu_reader)
return reader_table[slot].send_apdu_reader (slot,
apdu, apdulen,
- buffer, buflen);
+ buffer, buflen, pininfo);
else
return SW_HOST_NOT_SUPPORTED;
}
-/* Send an APDU to the card in SLOT. The APDU is created from all
- given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1
- for LC won't sent this field and the data field; in this case DATA
- must also be passed as NULL. The return value is the status word
- or -1 for an invalid SLOT or other non card related error. If
- RETBUF is not NULL, it will receive an allocated buffer with the
- returned data. The length of that data will be put into
- *RETBUFLEN. The caller is reponsible for releasing the buffer even
- in case of errors. */
-int
-apdu_send_le(int slot, int class, int ins, int p0, int p1,
- int lc, const char *data, int le,
- unsigned char **retbuf, size_t *retbuflen)
+
+/* Core APDU trabceiver function. Parameters are described at
+ apdu_send_le with the exception of PININFO which indicates keypad
+ related operations if not NULL. */
+static int
+send_le (int slot, int class, int ins, int p0, int p1,
+ int lc, const char *data, int le,
+ unsigned char **retbuf, size_t *retbuflen,
+ struct pininfo_s *pininfo)
{
#define RESULTLEN 256
unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in
@@ -2570,7 +2631,7 @@
/* As safeguard don't pass any garbage from the stack to the driver. */
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo);
if (rc || resultlen < 2)
{
log_error ("apdu_send_simple(%d) failed: %s\n",
@@ -2638,7 +2699,7 @@
apdu[apdulen++] = len;
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_simple(%d) for get response failed: %s\n",
@@ -2704,6 +2765,27 @@
}
/* Send an APDU to the card in SLOT. The APDU is created from all
+ given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1
+ for LC won't sent this field and the data field; in this case DATA
+ must also be passed as NULL. The return value is the status word
+ or -1 for an invalid SLOT or other non card related error. If
+ RETBUF is not NULL, it will receive an allocated buffer with the
+ returned data. The length of that data will be put into
+ *RETBUFLEN. The caller is reponsible for releasing the buffer even
+ in case of errors. */
+int
+apdu_send_le(int slot, int class, int ins, int p0, int p1,
+ int lc, const char *data, int le,
+ unsigned char **retbuf, size_t *retbuflen)
+{
+ return send_le (slot, class, ins, p0, p1,
+ lc, data, le,
+ retbuf, retbuflen,
+ NULL);
+}
+
+
+/* Send an APDU to the card in SLOT. The APDU is created from all
given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for
LC won't sent this field and the data field; in this case DATA must
also be passed as NULL. The return value is the status word or -1
@@ -2716,8 +2798,8 @@
apdu_send (int slot, int class, int ins, int p0, int p1,
int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
{
- return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256,
- retbuf, retbuflen);
+ return send_le (slot, class, ins, p0, p1, lc, data, 256,
+ retbuf, retbuflen, NULL);
}
/* Send an APDU to the card in SLOT. The APDU is created from all
@@ -2730,10 +2812,28 @@
apdu_send_simple (int slot, int class, int ins, int p0, int p1,
int lc, const char *data)
{
- return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL);
+ return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL);
}
+/* Same as apdu_send_simple but uses the keypad of the reader. */
+int
+apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1,
+ int lc, const char *data,
+ int pin_mode,
+ int pinlen_min, int pinlen_max, int pin_padlen)
+{
+ struct pininfo_s pininfo;
+
+ pininfo.mode = pin_mode;
+ pininfo.minlen = pinlen_min;
+ pininfo.maxlen = pinlen_max;
+ pininfo.padlen = pin_padlen;
+ return send_le (slot, class, ins, p0, p1, lc, data, -1,
+ NULL, NULL, &pininfo);
+}
+
+
/* This is a more generic version of the apdu sending routine. It
takes an already formatted APDU in APDUDATA or length APDUDATALEN
and returns the with the APDU including the status word. With
@@ -2771,7 +2871,7 @@
class = apdulen? *apdu : 0;
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_direct(%d) failed: %s\n",
@@ -2825,7 +2925,7 @@
apdu[apdulen++] = len;
memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
resultlen = RESULTLEN;
- rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
+ rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL);
if (rc || resultlen < 2)
{
log_error ("apdu_send_direct(%d) for get response failed: %s\n",
Modified: branches/GNUPG-1-9-BRANCH/scd/apdu.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/apdu.h 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/apdu.h 2005-11-28 11:52:25 UTC (rev 3947)
@@ -63,7 +63,8 @@
SW_HOST_CARD_IO_ERROR = 0x1000a,
SW_HOST_GENERAL_ERROR = 0x1000b,
SW_HOST_NO_READER = 0x1000c,
- SW_HOST_ABORTED = 0x1000d
+ SW_HOST_ABORTED = 0x1000d,
+ SW_HOST_NO_KEYPAD = 0x1000e
};
@@ -96,8 +97,14 @@
int apdu_reset (int slot);
int apdu_get_status (int slot, int hang,
unsigned int *status, unsigned int *changed);
+int apdu_check_keypad (int slot, int command, int pin_mode,
+ int pinlen_min, int pinlen_max, int pin_padlen);
int apdu_send_simple (int slot, int class, int ins, int p0, int p1,
int lc, const char *data);
+int apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1,
+ int lc, const char *data,
+ int pin_mode,
+ int pinlen_min, int pinlen_max, int pin_padlen);
int apdu_send (int slot, int class, int ins, int p0, int p1,
int lc, const char *data,
unsigned char **retbuf, size_t *retbuflen);
Modified: branches/GNUPG-1-9-BRANCH/scd/app-dinsig.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/app-dinsig.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/app-dinsig.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,5 +1,5 @@
/* app-dinsig.c - The DINSIG (DIN V 66291-1) card application.
- * Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -280,10 +280,11 @@
{
if (!app->did_chv1 || app->force_chv1 )
{
+ const char *s;
char *pinvalue;
int rc;
- rc = pincb (pincb_arg, "PIN", &pinvalue);
+ rc = pincb (pincb_arg, "PIN", &pinvalue);
if (rc)
{
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
@@ -291,8 +292,16 @@
}
/* We require the PIN to be at least 6 and at max 8 bytes.
- According to the specs, this should all be ASCII but we don't
- check this. */
+ According to the specs, this should all be ASCII. */
+ for (s=pinvalue; digitp (s); s++)
+ ;
+ if (*s)
+ {
+ log_error ("Non-numeric digits found in PIN\n");
+ xfree (pinvalue);
+ return gpg_error (GPG_ERR_BAD_PIN);
+ }
+
if (strlen (pinvalue) < 6)
{
log_error ("PIN is too short; minimum length is 6\n");
@@ -307,6 +316,28 @@
}
rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue));
+ if (gpg_err_code (rc) == GPG_ERR_INV_VALUE)
+ {
+ /* We assume that ISO 9564-1 encoding is used and we failed
+ because the first nibble we passed was 3 and not 2. DIN
+ says something about looking up such an encoding in the
+ SSD but I was not able to find any tag relevant to
+ this. */
+ char paddedpin[8];
+ int i, ndigits;
+
+ for (ndigits=0, s=pinvalue; *s; ndigits++, s++)
+ ;
+ i = 0;
+ paddedpin[i++] = 0x20 | (ndigits & 0x0f);
+ for (s=pinvalue; i < sizeof paddedpin && *s && s[1]; s = s+2 )
+ paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f));
+ if (i < sizeof paddedpin && *s)
+ paddedpin[i++] = (((*s - '0') << 4) | 0x0f);
+ while (i < sizeof paddedpin)
+ paddedpin[i++] = 0xff;
+ rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin);
+ }
if (rc)
{
log_error ("verify PIN failed\n");
@@ -404,7 +435,7 @@
int slot = app->slot;
int rc;
- rc = iso7816_select_application (slot, aid, sizeof aid);
+ rc = iso7816_select_application (slot, aid, sizeof aid, 0);
if (!rc)
{
app->apptype = "DINSIG";
Modified: branches/GNUPG-1-9-BRANCH/scd/app-nks.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/app-nks.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/app-nks.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -27,7 +27,7 @@
#include <time.h>
#include "scdaemon.h"
-
+#include "i18n.h"
#include "iso7816.h"
#include "app-common.h"
#include "tlv.h"
@@ -320,7 +320,7 @@
return rc;
}
- /* The follwoing limits are due to TCOS but also defined in the
+ /* The following limits are due to TCOS but also defined in the
NKS specs. */
if (strlen (pinvalue) < 6)
{
@@ -340,7 +340,10 @@
rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue));
if (rc)
{
- log_error ("verify PIN failed\n");
+ if ( gpg_error (rc) == GPG_ERR_USE_CONDITIONS )
+ log_error (_("the NullPIN has not yet been changed\n"));
+ else
+ log_error ("verify PIN failed\n");
xfree (pinvalue);
return rc;
}
@@ -492,7 +495,7 @@
int slot = app->slot;
int rc;
- rc = iso7816_select_application (slot, aid, sizeof aid);
+ rc = iso7816_select_application (slot, aid, sizeof aid, 0);
if (!rc)
{
app->apptype = "NKS";
Modified: branches/GNUPG-1-9-BRANCH/scd/app-openpgp.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/app-openpgp.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/app-openpgp.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1284,7 +1284,12 @@
if (!app->did_chv2)
{
char *pinvalue;
+ iso7816_pininfo_t pininfo;
+ memset (&pininfo, 0, sizeof pininfo);
+ pininfo.mode = 1;
+ pininfo.minlen = 6;
+
rc = pincb (pincb_arg, "PIN", &pinvalue);
if (rc)
{
@@ -2455,7 +2460,9 @@
size_t buflen;
void *relptr;
- rc = iso7816_select_application (slot, aid, sizeof aid);
+ /* Note that the card can't cope with P2=0xCO, thus we need to pass a
+ special flag value. */
+ rc = iso7816_select_application (slot, aid, sizeof aid, 0x0001);
if (!rc)
{
unsigned int manufacturer;
Modified: branches/GNUPG-1-9-BRANCH/scd/app-p15.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/app-p15.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/app-p15.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -3268,18 +3268,15 @@
int direct = 0;
int is_belpic = 0;
- rc = iso7816_select_application (slot, pkcs15_aid, sizeof pkcs15_aid);
+ rc = iso7816_select_application (slot, pkcs15_aid, sizeof pkcs15_aid, 0);
if (rc)
- {
- rc = iso7816_select_application (slot, pkcs15be_aid,sizeof pkcs15be_aid);
- if (!rc)
- is_belpic = 1;
- }
- if (rc)
{ /* Not found: Try to locate it from 2F00. We use direct path
selection here because it seems that the Belgian eID card
does only allow for that. Many other cards supports this
- selection method too. */
+ selection method too. Note, that we don't use
+ select_application above for the Belgian card - the call
+ works but it seems that it did not switch to the correct DF.
+ Using the 2f02 just works. */
unsigned short path[1] = { 0x2f00 };
rc = iso7816_select_path (app->slot, path, 1, NULL, NULL);
Modified: branches/GNUPG-1-9-BRANCH/scd/ccid-driver.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/ccid-driver.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/ccid-driver.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1240,7 +1240,9 @@
if (CCID_COMMAND_FAILED (buffer))
print_command_failed (buffer);
- /* Check whether a card is at all available. */
+ /* Check whether a card is at all available. Note: If you add new
+ error codes here, check whether they need to be ignored in
+ send_escape_cmd. */
switch ((buffer[7] & 0x03))
{
case 0: /* no error */ break;
@@ -1253,16 +1255,23 @@
/* Note that this function won't return the error codes NO_CARD or
- CARD_INACTIVE */
+ CARD_INACTIVE. IF RESULT is not NULL, the result from the
+ operation will get returned in RESULT and its length in RESULTLEN.
+ If the response is larger than RESULTMAX, an error is returned and
+ the required buffer length returned in RESULTLEN. */
static int
send_escape_cmd (ccid_driver_t handle,
- const unsigned char *data, size_t datalen)
+ const unsigned char *data, size_t datalen,
+ unsigned char *result, size_t resultmax, size_t *resultlen)
{
int i, rc;
unsigned char msg[100];
size_t msglen;
unsigned char seqno;
+ if (resultlen)
+ *resultlen = 0;
+
if (datalen > sizeof msg - 10)
return CCID_DRIVER_ERR_INV_VALUE; /* Escape data too large. */
@@ -1285,11 +1294,42 @@
return rc;
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Escape,
seqno, 5000, 0);
-
+ if (result)
+ switch (rc)
+ {
+ /* We need to ignore certain errorcode here. */
+ case 0:
+ case CCID_DRIVER_ERR_CARD_INACTIVE:
+ case CCID_DRIVER_ERR_NO_CARD:
+ {
+ if (msglen > resultmax)
+ rc = CCID_DRIVER_ERR_INV_VALUE; /* Response too large. */
+ else
+ {
+ memcpy (result, msg, msglen);
+ *resultlen = msglen;
+ }
+ rc = 0;
+ }
+ break;
+ default:
+ break;
+ }
+
return rc;
}
+int
+ccid_transceive_escape (ccid_driver_t handle,
+ const unsigned char *data, size_t datalen,
+ unsigned char *resp, size_t maxresplen, size_t *nresp)
+{
+ return send_escape_cmd (handle, data, datalen, resp, maxresplen, nresp);
+}
+
+
+
/* experimental */
int
ccid_poll (ccid_driver_t handle)
@@ -1445,7 +1485,8 @@
{
tried_iso = 1;
/* Try switching to ISO mode. */
- if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2))
+ if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2,
+ NULL, 0, NULL))
goto again;
}
else if (CCID_COMMAND_FAILED (msg))
@@ -1957,14 +1998,16 @@
}
-/* Send the CCID Secure command to the reader. APDU_BUF should contain the APDU template. PIN_MODE defines now the pin gets formatted:
+/* Send the CCID Secure command to the reader. APDU_BUF should
+ contain the APDU template. PIN_MODE defines how the pin gets
+ formatted:
1 := The PIN is ASCII encoded and of variable length. The
length of the PIN entered will be put into Lc by the reader.
The APDU should me made up of 4 bytes without Lc.
PINLEN_MIN and PINLEN_MAX define the limits for the pin length. 0
- may be used t enable usbale defaults. PIN_PADLEN should be 0
+ may be used t enable reasonable defaults. PIN_PADLEN should be 0.
When called with RESP and NRESP set to NULL, the function will
merely check whether the reader supports the secure command for the
@@ -1996,7 +2039,7 @@
else if (apdu_buflen >= 4 && apdu_buf[1] == 0x24 && (handle->has_pinpad & 2))
return CCID_DRIVER_ERR_NOT_SUPPORTED; /* Not yet by our code. */
else
- return CCID_DRIVER_ERR_NOT_SUPPORTED;
+ return CCID_DRIVER_ERR_NO_KEYPAD;
if (pin_mode != 1)
return CCID_DRIVER_ERR_NOT_SUPPORTED;
@@ -2027,7 +2070,8 @@
if (handle->id_vendor == VENDOR_SCM)
{
DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n");
- rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3);
+ rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3,
+ NULL, 0, NULL);
if (rc)
return rc;
}
@@ -2044,7 +2088,7 @@
if (handle->id_vendor == VENDOR_SCM)
{
/* For the SPR532 the next 2 bytes need to be zero. We do this
- for all SCM product. Kudos to to Martin Paljak for this
+ for all SCM product. Kudos to Martin Paljak for this
hint. */
msg[13] = msg[14] = 0;
}
Modified: branches/GNUPG-1-9-BRANCH/scd/ccid-driver.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/ccid-driver.h 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/ccid-driver.h 2005-11-28 11:52:25 UTC (rev 3947)
@@ -58,7 +58,7 @@
#ifndef CCID_DRIVER_H
#define CCID_DRIVER_H
-/* The CID driver returns the same error codes as the statsu words
+/* The CID driver returns the same error codes as the status words
used by GnuPG's apdu.h. For ease of maintenance they should always
match. */
#define CCID_DRIVER_ERR_OUT_OF_CORE 0x10001
@@ -74,6 +74,7 @@
#define CCID_DRIVER_ERR_GENERAL_ERROR 0x1000b
#define CCID_DRIVER_ERR_NO_READER 0x1000c
#define CCID_DRIVER_ERR_ABORTED 0x1000d
+#define CCID_DRIVER_ERR_NO_KEYPAD 0x1000e
struct ccid_driver_s;
typedef struct ccid_driver_s *ccid_driver_t;
@@ -94,6 +95,10 @@
int pin_mode,
int pinlen_min, int pinlen_max, int pin_padlen,
unsigned char *resp, size_t maxresplen, size_t *nresp);
+int ccid_transceive_escape (ccid_driver_t handle,
+ const unsigned char *data, size_t datalen,
+ unsigned char *resp, size_t maxresplen,
+ size_t *nresp);
Modified: branches/GNUPG-1-9-BRANCH/scd/iso7816.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/iso7816.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/iso7816.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -47,9 +47,9 @@
#define CMD_SELECT_FILE 0xA4
-#define CMD_VERIFY 0x20
-#define CMD_CHANGE_REFERENCE_DATA 0x24
-#define CMD_RESET_RETRY_COUNTER 0x2C
+#define CMD_VERIFY ISO7816_VERIFY
+#define CMD_CHANGE_REFERENCE_DATA ISO7816_CHANGE_REFERENCE_DATA
+#define CMD_RESET_RETRY_COUNTER ISO7816_RESET_RETRY_COUNTER
#define CMD_GET_DATA 0xCA
#define CMD_PUT_DATA 0xDA
#define CMD_MSE 0x22
@@ -95,6 +95,7 @@
case SW_HOST_GENERAL_ERROR: ec = GPG_ERR_GENERAL; break;
case SW_HOST_NO_READER: ec = GPG_ERR_ENODEV; break;
case SW_HOST_ABORTED: ec = GPG_ERR_CANCELED; break;
+ case SW_HOST_NO_KEYPAD: ec = GPG_ERR_NOT_SUPPORTED; break;
default:
if ((sw & 0x010000))
@@ -124,12 +125,15 @@
requested application ID. The function can't be used to enumerate
AIDs and won't return the AID on success. The return value is 0
for okay or a GPG error code. Note that ISO error codes are
- internally mapped. */
+ internally mapped. Bit 0 of FLAGS should be set if the card does
+ not understand P2=0xC0. */
gpg_error_t
-iso7816_select_application (int slot, const char *aid, size_t aidlen)
+iso7816_select_application (int slot, const char *aid, size_t aidlen,
+ unsigned int flags)
{
int sw;
- sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, 0, aidlen, aid);
+ sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4,
+ (flags&1)? 0 :0x0c, aidlen, aid);
return map_sw (sw);
}
@@ -221,27 +225,59 @@
}
+/* Check whether the reader supports the ISO command code COMMAND on
+ the keypad. Returns 0 on success. */
+gpg_error_t
+iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo)
+{
+ int sw;
+ sw = apdu_check_keypad (slot, command,
+ pininfo->mode, pininfo->minlen, pininfo->maxlen,
+ pininfo->padlen);
+ return map_sw (sw);
+}
+
+
/* Perform a VERIFY command on SLOT using the card holder verification
- vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */
+ vector CHVNO with a CHV of lenght CHVLEN. With PININFO non-NULL
+ the keypad of the reader will be used. Returns 0 on success. */
gpg_error_t
-iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
+iso7816_verify_kp (int slot, int chvno, const char *chv, size_t chvlen,
+ iso7816_pininfo_t *pininfo)
{
int sw;
- sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv);
+ if (pininfo && pininfo->mode)
+ sw = apdu_send_simple_kp (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv,
+ pininfo->mode,
+ pininfo->minlen,
+ pininfo->maxlen,
+ pininfo->padlen);
+ else
+ sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv);
return map_sw (sw);
}
+/* Perform a VERIFY command on SLOT using the card holder verification
+ vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */
+gpg_error_t
+iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
+{
+ return iso7816_verify_kp (slot, chvno, chv, chvlen, NULL);
+}
+
/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN
0), a "change reference data" is done, otherwise an "exchange
reference data". The new reference data is expected in NEWCHV of
- length NEWCHVLEN. */
+ length NEWCHVLEN. With PININFO non-NULL the keypad of the reader
+ will be used. */
gpg_error_t
-iso7816_change_reference_data (int slot, int chvno,
- const char *oldchv, size_t oldchvlen,
- const char *newchv, size_t newchvlen)
+iso7816_change_reference_data_kp (int slot, int chvno,
+ const char *oldchv, size_t oldchvlen,
+ const char *newchv, size_t newchvlen,
+ iso7816_pininfo_t *pininfo)
{
int sw;
char *buf;
@@ -258,28 +294,69 @@
memcpy (buf, oldchv, oldchvlen);
memcpy (buf+oldchvlen, newchv, newchvlen);
- sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
- oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf);
+ if (pininfo && pininfo->mode)
+ sw = apdu_send_simple_kp (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
+ oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf,
+ pininfo->mode,
+ pininfo->minlen,
+ pininfo->maxlen,
+ pininfo->padlen);
+ else
+ sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
+ oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf);
xfree (buf);
return map_sw (sw);
}
+/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
+ verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN
+ 0), a "change reference data" is done, otherwise an "exchange
+ reference data". The new reference data is expected in NEWCHV of
+ length NEWCHVLEN. */
gpg_error_t
-iso7816_reset_retry_counter (int slot, int chvno,
- const char *newchv, size_t newchvlen)
+iso7816_change_reference_data (int slot, int chvno,
+ const char *oldchv, size_t oldchvlen,
+ const char *newchv, size_t newchvlen)
{
+ return iso7816_change_reference_data_kp (slot, chvno, oldchv, oldchvlen,
+ newchv, newchvlen, NULL);
+}
+
+
+gpg_error_t
+iso7816_reset_retry_counter_kp (int slot, int chvno,
+ const char *newchv, size_t newchvlen,
+ iso7816_pininfo_t *pininfo)
+{
int sw;
if (!newchv || !newchvlen )
return gpg_error (GPG_ERR_INV_VALUE);
- sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER,
- 2, chvno, newchvlen, newchv);
+ if (pininfo && pininfo->mode)
+ sw = apdu_send_simple_kp (slot, 0x00, CMD_RESET_RETRY_COUNTER,
+ 2, chvno, newchvlen, newchv,
+ pininfo->mode,
+ pininfo->minlen,
+ pininfo->maxlen,
+ pininfo->padlen);
+ else
+ sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER,
+ 2, chvno, newchvlen, newchv);
return map_sw (sw);
}
+gpg_error_t
+iso7816_reset_retry_counter (int slot, int chvno,
+ const char *newchv, size_t newchvlen)
+{
+ return iso7816_reset_retry_counter_kp (slot, chvno, newchv, newchvlen, NULL);
+}
+
+
+
/* Perform a GET DATA command requesting TAG and storing the result in
a newly allocated buffer at the address passed by RESULT. Return
the length of this data at the address of RESULTLEN. */
Modified: branches/GNUPG-1-9-BRANCH/scd/iso7816.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/iso7816.h 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/iso7816.h 2005-11-28 11:52:25 UTC (rev 3947)
@@ -28,10 +28,30 @@
#include "cardglue.h"
#endif
+/* Command codes used by iso7816_check_keypad. */
+#define ISO7816_VERIFY 0x20
+#define ISO7816_CHANGE_REFERENCE_DATA 0x24
+#define ISO7816_RESET_RETRY_COUNTER 0x2C
+
+
+/* Information to be passed to keypad equipped readers. See
+ ccid-driver.c for details. */
+struct iso7816_pininfo_s
+{
+ int mode; /* A mode of 0 means: Do not use the keypad. */
+ int minlen;
+ int maxlen;
+ int padlen;
+ int padchar;
+};
+typedef struct iso7816_pininfo_s iso7816_pininfo_t;
+
+
gpg_error_t iso7816_map_sw (int sw);
gpg_error_t iso7816_select_application (int slot,
- const char *aid, size_t aidlen);
+ const char *aid, size_t aidlen,
+ unsigned int flags);
gpg_error_t iso7816_select_file (int slot, int tag, int is_dir,
unsigned char **result, size_t *resultlen);
gpg_error_t iso7816_select_path (int slot,
@@ -39,13 +59,26 @@
unsigned char **result, size_t *resultlen);
gpg_error_t iso7816_list_directory (int slot, int list_dirs,
unsigned char **result, size_t *resultlen);
+gpg_error_t iso7816_check_keypad (int slot, int command,
+ iso7816_pininfo_t *pininfo);
gpg_error_t iso7816_verify (int slot,
int chvno, const char *chv, size_t chvlen);
+gpg_error_t iso7816_verify_kp (int slot,
+ int chvno, const char *chv, size_t chvlen,
+ iso7816_pininfo_t *pininfo);
gpg_error_t iso7816_change_reference_data (int slot, int chvno,
const char *oldchv, size_t oldchvlen,
const char *newchv, size_t newchvlen);
+gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno,
+ const char *oldchv, size_t oldchvlen,
+ const char *newchv, size_t newchvlen,
+ iso7816_pininfo_t *pininfo);
gpg_error_t iso7816_reset_retry_counter (int slot, int chvno,
const char *newchv, size_t newchvlen);
+gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno,
+ const char *newchv,
+ size_t newchvlen,
+ iso7816_pininfo_t *pininfo);
gpg_error_t iso7816_get_data (int slot, int tag,
unsigned char **result, size_t *resultlen);
gpg_error_t iso7816_put_data (int slot, int tag,
Modified: branches/GNUPG-1-9-BRANCH/scd/scdaemon.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/scdaemon.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/scdaemon.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -84,6 +84,7 @@
opcscDriver,
oDisableCCID,
oDisableOpenSC,
+ oDisableKeypad,
oAllowAdmin,
oDenyAdmin,
oDisableApplication,
@@ -126,6 +127,7 @@
"@"
#endif
/* end --disable-ccid */},
+ { oDisableKeypad, "disable-keypad", 0, N_("do not use a reader's keypad")},
{ oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")},
{ oDenyAdmin, "deny-admin", 0, "@" },
{ oDisableApplication, "disable-application", 2, "@"},
@@ -135,7 +137,7 @@
/* The card dirver we use by default for PC/SC. */
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__)
#define DEFAULT_PCSC_DRIVER "winscard.dll"
#else
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
@@ -489,6 +491,8 @@
case oDisableCCID: opt.disable_ccid = 1; break;
case oDisableOpenSC: break;
+ case oDisableKeypad: opt.disable_keypad = 1; break;
+
case oAllowAdmin: opt.allow_admin = 1; break;
case oDenyAdmin: opt.allow_admin = 0; break;
Modified: branches/GNUPG-1-9-BRANCH/scd/scdaemon.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/scd/scdaemon.h 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/scd/scdaemon.h 2005-11-28 11:52:25 UTC (rev 3947)
@@ -39,21 +39,22 @@
#define MAX_DIGEST_LEN 24
-/* A large struct name "opt" to keep global flags */
+/* A large struct name "opt" to keep global flags. */
struct {
- unsigned int debug; /* debug flags (DBG_foo_VALUE) */
- int verbose; /* verbosity level */
- int quiet; /* be as quiet as possible */
- int dry_run; /* don't change any persistent data */
- int batch; /* batch mode */
- const char *homedir; /* configuration directory name */
+ unsigned int debug; /* Debug flags (DBG_foo_VALUE). */
+ int verbose; /* Verbosity level. */
+ int quiet; /* Be as quiet as possible. */
+ int dry_run; /* Don't change any persistent data. */
+ int batch; /* Batch mode. */
+ const char *homedir; /* Configuration directory name. */
const char *ctapi_driver; /* Library to access the ctAPI. */
const char *pcsc_driver; /* Library to access the PC/SC system. */
const char *reader_port; /* NULL or reder port to use. */
int disable_ccid; /* Disable the use of the internal CCID driver. */
+ int disable_keypad; /* Do not use a keypad. */
int allow_admin; /* Allow the use of admin commands for certain
cards. */
- strlist_t disabled_applications; /* card applications we do not
+ strlist_t disabled_applications; /* Card applications we do not
want to use. */
} opt;
Modified: branches/GNUPG-1-9-BRANCH/tools/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/tools/ChangeLog 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/tools/ChangeLog 2005-11-28 11:52:25 UTC (rev 3947)
@@ -1,3 +1,11 @@
+2005-10-19 Werner Koch <wk at g10code.com>
+
+ * gpgconf-comp.c (gc_options_scdaemon): New option --disable-keypad.
+
+2005-09-22 Werner Koch <wk at g10code.com>
+
+ * rfc822parse.c (parse_field): Tread Content-Disposition special.
+
2005-10-08 Marcus Brinkmann <marcus at g10code.de>
* Makefile.am (watchgnupg_LDADD): New variable.
Modified: branches/GNUPG-1-9-BRANCH/tools/gpgconf-comp.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/tools/gpgconf-comp.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/tools/gpgconf-comp.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -528,8 +528,10 @@
{ "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT,
"gnupg", "do not use the internal CCID driver",
GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
+ { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED,
+ "gnupg", "do not use a reader's keypad",
+ GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },
-
{ "Debug",
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
"gnupg", N_("Options useful for debugging") },
@@ -2447,7 +2449,8 @@
{
#ifdef HAVE_W32_SYSTEM
/* FIXME: Won't work becuase W32 doesn't silently
- overwrite. */
+ overwrite. Fix it by creating a backup copy and
+ deliting the orginal file first. */
err = rename (src_pathname[i], dest_pathname[i]);
#else /*!HAVE_W32_SYSTEM*/
/* This is a bit safer than rename() because we
Modified: branches/GNUPG-1-9-BRANCH/tools/rfc822parse.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/tools/rfc822parse.c 2005-11-23 12:38:38 UTC (rev 3946)
+++ branches/GNUPG-1-9-BRANCH/tools/rfc822parse.c 2005-11-28 11:52:25 UTC (rev 3947)
@@ -766,6 +766,7 @@
} tspecial_header[] = {
{ "Content-Type", 12},
{ "Content-Transfer-Encoding", 25},
+ { "Content-Disposition", 19},
{ NULL, 0}
};
const char *delimiters;
More information about the Gnupg-commits
mailing list