diff options
author | Werner Koch <[email protected]> | 2020-01-13 17:24:01 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2020-01-13 17:24:01 +0000 |
commit | 2dd6b4b998dd6e156e2e75ede0f40fb768c69f40 (patch) | |
tree | c85dfbc707b24316925610bdfb7c5a7cecc5230a /scd/app-openpgp.c | |
parent | scd:piv: Implement PIN cache. (diff) | |
download | gnupg-2dd6b4b998dd6e156e2e75ede0f40fb768c69f40.tar.gz gnupg-2dd6b4b998dd6e156e2e75ede0f40fb768c69f40.zip |
scd: Make the PIN cache robust against wrongdoing of gpg-agent.
* scd/app-openpgp.c (struct app_local_s): New field pincache.
(cache_pin): Set it.
(pin_from_cache): Consult it.
* scd/app-piv.c (struct app_local_s): New field pincache.
(cache_pin): Set it.
(pin_from_cache): Consult it.
--
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'scd/app-openpgp.c')
-rw-r--r-- | scd/app-openpgp.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index ad88eb619..293c53cb5 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -215,6 +215,18 @@ struct app_local_s { unsigned int def_chv2:1; /* Use 123456 for CHV2. */ } flags; + + /* Keep track on whether we cache a certain PIN so that we get it + * from the cache only if we know we cached it. This inhibits the + * use of the same cache entry for a card plugged in and out without + * gpg-agent having noticed that due to a bug. */ + struct + { + unsigned int maybe_chv1:1; + unsigned int maybe_chv2:1; + unsigned int maybe_chv3:1; + } pincache; + /* Pinpad request specified on card. */ struct { @@ -223,8 +235,8 @@ struct app_local_s { int fixedlen_admin; } pinpad; - struct - { + struct + { key_type_t key_type; union { struct { @@ -240,6 +252,7 @@ struct app_local_s { } ecc; }; } keyattr[3]; + }; #define ECC_FLAG_DJB_TWEAK (1 << 0) @@ -2227,6 +2240,13 @@ cache_pin (app_t app, ctrl_t ctrl, int chvno, const char *pin) pincache_put (ctrl, app_get_slot (app), "openpgp", keyref, pin, pin? strlen (pin):0); + + switch (chvno) + { + case 1: app->app_local->pincache.maybe_chv1 = !!pin; break; + case 2: app->app_local->pincache.maybe_chv2 = !!pin; break; + case 3: app->app_local->pincache.maybe_chv3 = !!pin; break; + } } @@ -2237,6 +2257,7 @@ static int pin_from_cache (app_t app, ctrl_t ctrl, int chvno, char **r_pin) { const char *keyref = chvno_to_keyref (chvno); + int maybe_cached; *r_pin = NULL; @@ -2248,6 +2269,17 @@ pin_from_cache (app_t app, ctrl_t ctrl, int chvno, char **r_pin) default: return 0; } + switch (chvno) + { + case 1: maybe_cached = app->app_local->pincache.maybe_chv1; break; + case 2: maybe_cached = app->app_local->pincache.maybe_chv2; break; + case 3: maybe_cached = app->app_local->pincache.maybe_chv3; break; + default: maybe_cached = 0; break; + } + + if (!maybe_cached) + return 0; + if (pincache_get (ctrl, app_get_slot (app), "openpgp", keyref, r_pin)) return 0; @@ -2255,7 +2287,6 @@ pin_from_cache (app_t app, ctrl_t ctrl, int chvno, char **r_pin) } - /* Verify a CHV either using the pinentry or if possible by using a pinpad. PINCB and PINCB_ARG describe the usual callback for the pinentry. CHVNO must be either 1 or 2. SIGCOUNT is only |