aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app-p15.c
diff options
context:
space:
mode:
Diffstat (limited to 'scd/app-p15.c')
-rw-r--r--scd/app-p15.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/scd/app-p15.c b/scd/app-p15.c
index 8ede6c05e..5616e2e48 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -5004,6 +5004,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;
@@ -5016,11 +5023,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. */
@@ -5028,6 +5038,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->serialno && app->serialnolen == 4+9
+ && !memcmp (app->serialno, "\xff\x00\x00\xff", 4)
+ && !any_control_or_space_mem (app->serialno + 4, 9))
+ {
+ /* Sample: ff0000ff354830313232363537 -> "5H01 2265 7" */
+ serial = xtrymalloc (9+2+1);
+ if (serial)
+ {
+ s = 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))
@@ -5038,6 +5070,7 @@ get_dispserialno (app_t app, prkdf_object_t prkdf)
{
serial = app_get_serialno (app);
}
+
return serial;
}
@@ -5150,8 +5183,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;
@@ -5616,11 +5649,14 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
}
else if (prkdf->key_reference_valid)
{
- unsigned char mse[3];
+ unsigned char mse[6];
- mse[0] = 0x84; /* Select asym. key. */
+ mse[0] = 0x80;
mse[1] = 1;
- mse[2] = prkdf->key_reference;
+ mse[2] = 0x13; /* pkcs#1.5, sha-256 */
+ mse[3] = 0x84; /* Select asym. key. */
+ mse[4] = 1;
+ mse[5] = prkdf->key_reference;
err = iso7816_manage_security_env (app_get_slot (app),
0x41, 0xB6,