diff options
author | Werner Koch <wk@gnupg.org> | 2022-05-06 11:37:47 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2022-05-06 11:43:07 +0200 |
commit | 3d7d7e8bfd1259e00104b6d52c86d5554fe5b9dd (patch) | |
tree | e3bb19a5074e13ad1f4483b4e3e1fff9441727e9 /scd | |
parent | scd:p15: Fix the the sanity check of the displayed S/N. (diff) | |
download | gnupg2-3d7d7e8bfd1259e00104b6d52c86d5554fe5b9dd.tar.xz gnupg2-3d7d7e8bfd1259e00104b6d52c86d5554fe5b9dd.zip |
scd:p15: Improve the displayed S/N for Technology Nexus cards.
* scd/app-p15.c (any_control_or_space_mem): New.
(get_dispserialno): Add new code.
--
This works with my test cards and now reflects what's printed on the
front matter of the card.
Diffstat (limited to 'scd')
-rw-r--r-- | scd/app-p15.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/scd/app-p15.c b/scd/app-p15.c index fc136b9fb..ac6b875b8 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -5008,6 +5008,13 @@ any_control_or_space (const char *string) return 1; return 0; } + +static int +any_control_or_space_mem (const void *buffer, size_t buflen) +{ + const unsigned char *s; + + for (s = buffer; buflen; s++, buflen--) if (*s <= 0x20 || *s >= 0x7f) return 1; return 0; @@ -5020,11 +5027,14 @@ static char * get_dispserialno (app_t app, prkdf_object_t prkdf) { char *serial; + const unsigned char *s; + int i; size_t n; /* We prefer the SerialNumber RDN from the Subject-DN but we don't * use it if it features a percent sign (special character in pin - * prompts) or has any control character. */ + * prompts) or has any control character. For some cards we use a + * different strategy. */ if (app->app_local->card_product == CARD_PRODUCT_RSCS) { /* We use only the right 8 hex digits. */ @@ -5032,6 +5042,28 @@ get_dispserialno (app_t app, prkdf_object_t prkdf) if (serial && (n=strlen (serial)) > 8) memmove (serial, serial + n - 8, 9); } + else if (IS_CARDOS_5 (app) && app->app_local->manufacturer_id + && !ascii_strcasecmp (app->app_local->manufacturer_id, + "Technology Nexus") + && APP_CARD(app)->serialno && APP_CARD(app)->serialnolen == 4+9 + && !memcmp (APP_CARD(app)->serialno, "\xff\x00\x00\xff", 4) + && !any_control_or_space_mem (APP_CARD(app)->serialno + 4, 9)) + { + /* Sample: ff0000ff354830313232363537 -> "5H01 2265 7" */ + serial = xtrymalloc (9+2+1); + if (serial) + { + s = APP_CARD(app)->serialno + 4; + for (i=0; i < 4; i++) + serial[i] = *s++; + serial[i++] = ' '; + for (; i < 9; i++) + serial[i] = *s++; + serial[i++] = ' '; + serial[i++] = *s; + serial[i] = 0; + } + } else if (prkdf && prkdf->serial_number && *prkdf->serial_number && !strchr (prkdf->serial_number, '%') && !any_control_or_space (prkdf->serial_number)) @@ -5042,6 +5074,7 @@ get_dispserialno (app_t app, prkdf_object_t prkdf) { serial = app_get_serialno (app); } + return serial; } @@ -5154,8 +5187,8 @@ verify_pin (app_t app, { /* We know that this card supports a verify status check. Note * that in contrast to PIV cards ISO7816_VERIFY_NOT_NEEDED is - * not supported. Noet that we don't use the pin_verified cache - * status because that is not as reliable than to ask the card + * not supported. We also don't use the pin_verified cache + * status because that is not as reliable as to ask the card * about its state. */ if (prkdf) /* Clear the cache which we don't use. */ prkdf->pin_verified = 0; |