diff options
-rw-r--r-- | agent/agent.h | 2 | ||||
-rw-r--r-- | agent/command.c | 2 | ||||
-rw-r--r-- | agent/divert-scd.c | 2 | ||||
-rw-r--r-- | agent/keyformat.txt | 7 | ||||
-rw-r--r-- | agent/protect.c | 33 |
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; } |