1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-09 23:39:51 +02:00

scd: Disable pinpad if it's impossible by KDF DO.

* scd/app-openpgp.c (struct app_local_s): Add pinpad.disabled field.
(do_getattr): Set pinpad.disabled field.
(check_pinpad_request): Use the pinpad.disabled field.
(do_setattr): Update pinpad.disabled field.

--

GnuPG-bug-id: 4832
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
(cherry picked from commit 95c7498b76)
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
NIIBE Yutaka 2020-02-17 17:44:59 +09:00 committed by Werner Koch
parent fbe3184752
commit b27e20a95c
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B

View File

@ -71,6 +71,9 @@
#include "../common/openpgpdefs.h" #include "../common/openpgpdefs.h"
#define KDF_DATA_LENGTH_MIN 90
#define KDF_DATA_LENGTH_MAX 110
/* A table describing the DOs of the card. */ /* A table describing the DOs of the card. */
static struct { static struct {
int tag; int tag;
@ -200,7 +203,7 @@ struct app_local_s {
unsigned int private_dos:1; unsigned int private_dos:1;
unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */ unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */
unsigned int has_decrypt:1; /* Support symmetric decryption. */ unsigned int has_decrypt:1; /* Support symmetric decryption. */
unsigned int kdf_do:1; /* Support KDF DO. */ unsigned int kdf_do:1; /* Support KDF DO. */
unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */ unsigned int sm_algo:2; /* Symmetric crypto algo for SM. */
unsigned int pin_blk2:1; /* PIN block 2 format supported. */ unsigned int pin_blk2:1; /* PIN block 2 format supported. */
@ -220,6 +223,7 @@ struct app_local_s {
/* Pinpad request specified on card. */ /* Pinpad request specified on card. */
struct struct
{ {
unsigned int disabled:1; /* No pinpad use because of KDF DO. */
unsigned int specified:1; unsigned int specified:1;
int fixedlen_user; int fixedlen_user;
int fixedlen_admin; int fixedlen_admin;
@ -987,7 +991,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
{ "$ENCRKEYID", 0x0000, -6 }, { "$ENCRKEYID", 0x0000, -6 },
{ "$SIGNKEYID", 0x0000, -7 }, { "$SIGNKEYID", 0x0000, -7 },
{ "$DISPSERIALNO",0x0000, -4 }, { "$DISPSERIALNO",0x0000, -4 },
{ "KDF", 0x00F9 }, { "KDF", 0x00F9, 5 },
{ NULL, 0 } { NULL, 0 }
}; };
int idx, i, rc; int idx, i, rc;
@ -1112,11 +1116,25 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
for (i=0; i < 3; i++) for (i=0; i < 3; i++)
send_fprtime_if_not_null (ctrl, table[idx].name, i+1, value+i*4); send_fprtime_if_not_null (ctrl, table[idx].name, i+1, value+i*4);
} }
else if (table[idx].special == 5)
{
if ((valuelen == KDF_DATA_LENGTH_MIN
|| valuelen == KDF_DATA_LENGTH_MAX)
&& (value[2] == 0x03))
app->app_local->pinpad.disabled = 1;
else
app->app_local->pinpad.disabled = 0;
}
else else
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0); send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
xfree (relptr); xfree (relptr);
} }
else
{
if (table[idx].special == 5)
app->app_local->pinpad.disabled = 0;
}
return rc; return rc;
} }
@ -1993,6 +2011,9 @@ do_readcert (app_t app, const char *certid,
static int static int
check_pinpad_request (app_t app, pininfo_t *pininfo, int admin_pin) check_pinpad_request (app_t app, pininfo_t *pininfo, int admin_pin)
{ {
if (app->app_local->pinpad.disabled)
return 1;
if (app->app_local->pinpad.specified == 0) /* No preference on card. */ if (app->app_local->pinpad.specified == 0) /* No preference on card. */
{ {
if (pininfo->fixedlen == 0) /* Reader has varlen capability. */ if (pininfo->fixedlen == 0) /* Reader has varlen capability. */
@ -2087,9 +2108,6 @@ get_prompt_info (app_t app, int chvno, unsigned long sigcount, int remaining)
return result; return result;
} }
#define KDF_DATA_LENGTH_MIN 90
#define KDF_DATA_LENGTH_MAX 110
/* Compute hash if KDF-DO is available. CHVNO must be 0 for reset /* Compute hash if KDF-DO is available. CHVNO must be 0 for reset
code, 1 or 2 for user pin and 3 for admin pin. code, 1 or 2 for user pin and 3 for admin pin.
*/ */
@ -2540,6 +2558,12 @@ do_setattr (app_t app, const char *name,
app->did_chv1 = 0; app->did_chv1 = 0;
app->did_chv2 = 0; app->did_chv2 = 0;
app->did_chv3 = 0; app->did_chv3 = 0;
if ((valuelen == KDF_DATA_LENGTH_MIN || valuelen == KDF_DATA_LENGTH_MAX)
&& (value[2] == 0x03))
app->app_local->pinpad.disabled = 1;
else
app->app_local->pinpad.disabled = 0;
} }
return rc; return rc;
@ -4259,7 +4283,6 @@ check_against_given_fingerprint (app_t app, const char *fpr, int key)
} }
/* Compute a digital signature on INDATA which is expected to be the /* Compute a digital signature on INDATA which is expected to be the
raw message digest. For this application the KEYIDSTR consists of raw message digest. For this application the KEYIDSTR consists of
the serialnumber and the fingerprint delimited by a slash. the serialnumber and the fingerprint delimited by a slash.