aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/agent.h2
-rw-r--r--agent/command.c2
-rw-r--r--agent/divert-scd.c2
-rw-r--r--agent/keyformat.txt7
-rw-r--r--agent/protect.c33
5 files changed, 41 insertions, 5 deletions
diff --git a/agent/agent.h b/agent/agent.h
index d345c66a1..45bc507e3 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -394,7 +394,7 @@ int agent_shadow_key (const unsigned char *pubkey,
int agent_get_shadow_info (const unsigned char *shadowkey,
unsigned char const **shadow_info);
gpg_error_t parse_shadow_info (const unsigned char *shadow_info,
- char **r_hexsn, char **r_idstr);
+ char **r_hexsn, char **r_idstr, int *r_pinlen);
gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
int s2kmode,
const unsigned char *s2ksalt,
diff --git a/agent/command.c b/agent/command.c
index 9de3e47b9..88cd62c08 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1090,7 +1090,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
if (shadow_info)
{
- err = parse_shadow_info (shadow_info, &serialno, &idstr);
+ err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
if (err)
goto leave;
}
diff --git a/agent/divert-scd.c b/agent/divert-scd.c
index 59264243d..22cdf8ed9 100644
--- a/agent/divert-scd.c
+++ b/agent/divert-scd.c
@@ -44,7 +44,7 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
*r_kid = NULL;
- rc = parse_shadow_info (shadow_info, &want_sn, &want_kid);
+ rc = parse_shadow_info (shadow_info, &want_sn, &want_kid, NULL);
if (rc)
return rc;
diff --git a/agent/keyformat.txt b/agent/keyformat.txt
index 3ebba6e50..7ba6af2fb 100644
--- a/agent/keyformat.txt
+++ b/agent/keyformat.txt
@@ -155,7 +155,12 @@ to keys stored on a token:
The currently used protocol is "ti-v1" (token info version 1). The
second list with the information has this layout:
-(card_serial_number id_string_of_key)
+(card_serial_number id_string_of_key fixed_pin_length)
+
+FIXED_PIN_LENGTH is optional. It can be used to store the length of
+the PIN; a value of 0 indicates that this information is not
+available. The rationale for this field is that some pinpad equipped
+readers don't allow passing a variable length PIN.
More items may be added to the list.
diff --git a/agent/protect.c b/agent/protect.c
index 64af4ed8e..68e1a049f 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -1272,7 +1272,7 @@ agent_get_shadow_info (const unsigned char *shadowkey,
required, NULL may be passed for them. */
gpg_error_t
parse_shadow_info (const unsigned char *shadow_info,
- char **r_hexsn, char **r_idstr)
+ char **r_hexsn, char **r_idstr, int *r_pinlen)
{
const unsigned char *s;
size_t n;
@@ -1281,6 +1281,8 @@ parse_shadow_info (const unsigned char *shadow_info,
*r_hexsn = NULL;
if (r_idstr)
*r_idstr = NULL;
+ if (r_pinlen)
+ *r_pinlen = 0;
s = shadow_info;
if (*s != '(')
@@ -1325,5 +1327,34 @@ parse_shadow_info (const unsigned char *shadow_info,
(*r_idstr)[n] = 0;
}
+ /* Parse the optional PINLEN. */
+ n = snext (&s);
+ if (!n)
+ return 0;
+
+ if (r_pinlen)
+ {
+ char *tmpstr = xtrymalloc (n+1);
+ if (!tmpstr)
+ {
+ if (r_hexsn)
+ {
+ xfree (*r_hexsn);
+ *r_hexsn = NULL;
+ }
+ if (r_idstr)
+ {
+ xfree (*r_idstr);
+ *r_idstr = NULL;
+ }
+ return gpg_error_from_syserror ();
+ }
+ memcpy (tmpstr, s, n);
+ tmpstr[n] = 0;
+
+ *r_pinlen = (int)strtol (tmpstr, NULL, 10);
+ xfree (tmpstr);
+ }
+
return 0;
}