aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scd/app-openpgp.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index eac71a251..95b9a359b 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -71,6 +71,9 @@
#include "../common/openpgpdefs.h"
+#define KDF_DATA_LENGTH_MIN 90
+#define KDF_DATA_LENGTH_MAX 110
+
/* A table describing the DOs of the card. */
static struct {
int tag;
@@ -200,7 +203,7 @@ struct app_local_s {
unsigned int private_dos:1;
unsigned int algo_attr_change:1; /* Algorithm attributes changeable. */
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 pin_blk2:1; /* PIN block 2 format supported. */
@@ -220,6 +223,7 @@ struct app_local_s {
/* Pinpad request specified on card. */
struct
{
+ unsigned int disabled:1; /* No pinpad use because of KDF DO. */
unsigned int specified:1;
int fixedlen_user;
int fixedlen_admin;
@@ -987,7 +991,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
{ "$ENCRKEYID", 0x0000, -6 },
{ "$SIGNKEYID", 0x0000, -7 },
{ "$DISPSERIALNO",0x0000, -4 },
- { "KDF", 0x00F9 },
+ { "KDF", 0x00F9, 5 },
{ NULL, 0 }
};
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++)
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
send_status_info (ctrl, table[idx].name, value, valuelen, NULL, 0);
xfree (relptr);
}
+ else
+ {
+ if (table[idx].special == 5)
+ app->app_local->pinpad.disabled = 0;
+ }
return rc;
}
@@ -1993,6 +2011,9 @@ do_readcert (app_t app, const char *certid,
static int
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 (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;
}
-#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
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_chv2 = 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;
@@ -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
raw message digest. For this application the KEYIDSTR consists of
the serialnumber and the fingerprint delimited by a slash.