mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd: Support longer data length for special DOs for v3 card.
* scd/app-openpgp.c (data_objects): Special DOs like "Login Data", "URL", "Private DO N" can be longer size >= 256. (struct app_local_s): Define bits for v3 card. (get_cached_data): Use extcap.max_special_do for special DOs. (app_select_openpgp): Detect if extcap_v3, kdf_do, and other bits. -- GnuPG-bug-id: 3262 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
84146b3ec4
commit
69614d5501
@ -85,12 +85,15 @@ static struct {
|
||||
does not work with composite DO and
|
||||
is currently only useful for the CHV
|
||||
status bytes. */
|
||||
int try_extlen:1; /* Large object; try to use an extended
|
||||
length APDU. */
|
||||
int try_extlen:2; /* Large object; try to use an extended
|
||||
length APDU when !=0. The size is
|
||||
determined by extcap.max_certlen_3
|
||||
when == 1, and by extcap.max_special_do
|
||||
when == 2. */
|
||||
char *desc;
|
||||
} data_objects[] = {
|
||||
{ 0x005E, 0, 0, 1, 0, 0, 0, 0, "Login Data" },
|
||||
{ 0x5F50, 0, 0, 0, 0, 0, 0, 0, "URL" },
|
||||
{ 0x005E, 0, 0, 1, 0, 0, 0, 2, "Login Data" },
|
||||
{ 0x5F50, 0, 0, 0, 0, 0, 0, 2, "URL" },
|
||||
{ 0x5F52, 0, 0, 1, 0, 0, 0, 0, "Historical Bytes" },
|
||||
{ 0x0065, 1, 0, 1, 0, 0, 0, 0, "Cardholder Related Data"},
|
||||
{ 0x005B, 0, 0x65, 0, 0, 0, 0, 0, "Name" },
|
||||
@ -110,10 +113,10 @@ static struct {
|
||||
{ 0x00CD, 0, 0x6E, 1, 0, 0, 0, 0, "Generation time" },
|
||||
{ 0x007A, 1, 0, 1, 0, 0, 0, 0, "Security Support Template" },
|
||||
{ 0x0093, 0, 0x7A, 1, 1, 0, 0, 0, "Digital Signature Counter" },
|
||||
{ 0x0101, 0, 0, 0, 0, 0, 0, 0, "Private DO 1"},
|
||||
{ 0x0102, 0, 0, 0, 0, 0, 0, 0, "Private DO 2"},
|
||||
{ 0x0103, 0, 0, 0, 0, 0, 0, 0, "Private DO 3"},
|
||||
{ 0x0104, 0, 0, 0, 0, 0, 0, 0, "Private DO 4"},
|
||||
{ 0x0101, 0, 0, 0, 0, 0, 0, 2, "Private DO 1"},
|
||||
{ 0x0102, 0, 0, 0, 0, 0, 0, 2, "Private DO 2"},
|
||||
{ 0x0103, 0, 0, 0, 0, 0, 0, 2, "Private DO 3"},
|
||||
{ 0x0104, 0, 0, 0, 0, 0, 0, 2, "Private DO 4"},
|
||||
{ 0x7F21, 1, 0, 1, 0, 0, 0, 1, "Cardholder certificate"},
|
||||
/* V3.0 */
|
||||
{ 0x7F74, 0, 0, 1, 0, 0, 0, 0, "General Feature Management"},
|
||||
@ -185,18 +188,25 @@ struct app_local_s {
|
||||
/* Keep track of extended card capabilities. */
|
||||
struct
|
||||
{
|
||||
unsigned int is_v2:1; /* This is a v2.0 compatible card. */
|
||||
unsigned int sm_supported:1; /* Secure Messaging is supported. */
|
||||
unsigned int is_v2:1; /* Compatible to v2 or later. */
|
||||
unsigned int extcap_v3:1; /* Extcap is in v3 format. */
|
||||
unsigned int has_button:1; /* Has confirmation button or not. */
|
||||
|
||||
unsigned int sm_supported:1; /* Secure Messaging is supported. */
|
||||
unsigned int get_challenge:1;
|
||||
unsigned int key_import:1;
|
||||
unsigned int change_force_chv:1;
|
||||
unsigned int private_dos:1;
|
||||
unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */
|
||||
unsigned int has_decrypt:1; /* Support symmetric decryption. */
|
||||
unsigned int has_button:1;
|
||||
unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */
|
||||
unsigned int has_decrypt:1; /* Support symmetric decryption. */
|
||||
unsigned int kdf_do:1; /* Support KDF DOs. */
|
||||
|
||||
unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */
|
||||
unsigned int pin_blk2:1; /* PIN block 2 format supported. */
|
||||
unsigned int mse:1; /* MSE command supported. */
|
||||
unsigned int max_certlen_3:16;
|
||||
unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */
|
||||
unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */
|
||||
unsigned int max_special_do:16; /* Maximum size for special DOs. */
|
||||
} extcap;
|
||||
|
||||
/* Flags used to control the application. */
|
||||
@ -323,7 +333,14 @@ get_cached_data (app_t app, int tag,
|
||||
}
|
||||
|
||||
if (try_extlen && app->app_local->cardcap.ext_lc_le)
|
||||
exmode = app->app_local->extcap.max_certlen_3;
|
||||
{
|
||||
if (try_extlen == 1)
|
||||
exmode = app->app_local->extcap.max_certlen_3;
|
||||
else if (try_extlen == 2 && app->app_local->extcap.extcap_v3)
|
||||
exmode = app->app_local->extcap.max_special_do;
|
||||
else
|
||||
exmode = 0;
|
||||
}
|
||||
else
|
||||
exmode = 0;
|
||||
|
||||
@ -5006,6 +5023,8 @@ app_select_openpgp (app_t app)
|
||||
if (app->card_version >= 0x0200)
|
||||
app->app_local->extcap.is_v2 = 1;
|
||||
|
||||
if (app->card_version >= 0x0300)
|
||||
app->app_local->extcap.extcap_v3 = 1;
|
||||
|
||||
/* Read the historical bytes. */
|
||||
relptr = get_one_do (app, 0x5f52, &buffer, &buflen, NULL);
|
||||
@ -5048,14 +5067,24 @@ app_select_openpgp (app_t app)
|
||||
app->app_local->extcap.private_dos = !!(*buffer & 0x08);
|
||||
app->app_local->extcap.algo_attr_change = !!(*buffer & 0x04);
|
||||
app->app_local->extcap.has_decrypt = !!(*buffer & 0x02);
|
||||
app->app_local->extcap.kdf_do = !!(*buffer & 0x01);
|
||||
}
|
||||
if (buflen >= 10)
|
||||
{
|
||||
/* Available with v2 cards. */
|
||||
/* Available with cards of v2 or later. */
|
||||
app->app_local->extcap.sm_algo = buffer[1];
|
||||
app->app_local->extcap.max_get_challenge
|
||||
= (buffer[2] << 8 | buffer[3]);
|
||||
app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]);
|
||||
|
||||
/* Interpretation is different between v2 and v3, unfortunately. */
|
||||
if (app->app_local->extcap.extcap_v3)
|
||||
{
|
||||
app->app_local->extcap.max_special_do
|
||||
= (buffer[6] << 8 | buffer[7]);
|
||||
app->app_local->extcap.pin_blk2 = !!(buffer[8] & 0x01);
|
||||
app->app_local->extcap.mse= !!(buffer[9] & 0x01);
|
||||
}
|
||||
}
|
||||
xfree (relptr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user