Hi Martin,

Viktor TARASOV wrote:
Martin Paljak wrote:
On Feb 3, 2010, at 18:41 , Viktor TARASOV wrote:
Maybe pin cache should be attached not to 'pkcs15_card', but to the PIN 'pkcs15_object' ? In object info there are path, reference, flags, ...
Why not. If objects get destroyed and don't leak it would probably be as good.
What would you say about pincache as a der-value of the pkcs15 PIN object? So that, to the existing API to access pkcs15 objects can be used to access pincache.

If no objections, I'll commit the final patch proposal for the libopensc part.


I've tested it in conjunction with another proposal, that replaces static keycache in the pkcs15init part (keycache is not needed in pkcs11). This second one is a little bit voluminous -- it contains the changes to the internal pkcs15init API, discussed in http://www.opensc-project.org/pipermail/opensc-devel/2010-February/013254.html

Together these two patches have been tested with Oberthur, CardOS ans SetCOS.

I'll wait for more cards to test, before submitting the second one.

Kind wishes,
Viktor.


--
Viktor Tarasov  <viktor.tara...@opentrust.com>

Index: src/libopensc/pkcs15-pin.c
===================================================================
--- src/libopensc/pkcs15-pin.c  (révision 4012)
+++ src/libopensc/pkcs15-pin.c  (copie de travail)
@@ -204,16 +204,17 @@
  */
 int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
                         struct sc_pkcs15_pin_info *pin,
-                        const u8 *pincode, size_t pinlen)
+                        const unsigned char *pincode, size_t pinlen)
 {
        int r;
        sc_card_t *card;
        struct sc_pin_cmd_data data;
 
        SC_FUNC_CALLED(p15card->card->ctx, 2);
-       if ((r = _validate_pin(p15card, pin, pinlen)) != SC_SUCCESS)
-               return r;
 
+       r = _validate_pin(p15card, pin, pinlen);
+       SC_TEST_RET(card->ctx, r, "PIN value do not conforms the PIN policy");
+
        card = p15card->card;
 
        r = sc_lock(card);
@@ -464,59 +465,53 @@
        free(pin);
 }
 
+
 /* Add a PIN to the PIN cache related to the card. Some operations can trigger 
re-authentication later. */
 static void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, 
        struct sc_pkcs15_pin_info *pininfo,
        const u8 *pin, size_t pinlen)
 {
-       int i;
-       sc_pkcs15_pincache_entry_t *entry;
-       sc_pkcs15_object_t *obj;
+       struct sc_context *ctx = p15card->card->ctx;
+       struct sc_pkcs15_object *obj = NULL;
+       int r;
 
-       SC_FUNC_CALLED(p15card->card->ctx, 2);
+       SC_FUNC_CALLED(ctx, 2);
 
        if (!p15card->opts.use_pin_cache)
                return;
 
+       r = sc_pkcs15_find_pin_by_reference(p15card, NULL, pininfo->reference, 
&obj);
+       if (r < 0)   {
+               sc_debug(ctx, "PIN with reference 0x%X not found", 
pininfo->reference);
+               return;
+       }
+               
        /* Is it a user consent protecting PIN ? */
-       if (sc_pkcs15_find_prkey_by_reference(p15card, NULL, 
pininfo->reference, &obj) == SC_SUCCESS) {
-               if (obj->user_consent) {
-                       sc_debug(p15card->card->ctx, "Not caching userconsent 
related PIN");
-                       return;
-               }
+       if (obj->user_consent) {
+               sc_debug(ctx, "Cache is not supported for the PIN related to 
'user consent'");
+               return;
        }
 
-       for (i=0; i<SC_PKCS15_MAX_PINS; i++) {
-               if (p15card->pin_cache[i] == NULL) {
-                       entry = (sc_pkcs15_pincache_entry_t *) 
sc_mem_alloc_secure(sizeof(sc_pkcs15_pincache_entry_t));
-                       if (!entry)
-                               return;
-                       memcpy(&entry->id, &pininfo->auth_id, 
sizeof(sc_pkcs15_id_t));
-                       memcpy(&entry->pin, pin, pinlen);
-                       entry->len = pinlen;
-                       entry->counter = 0;
-                       p15card->pin_cache[i] = entry;
-                       return;
-               } else { /* Update the existing PIN */
-                       sc_pkcs15_pincache_entry_t *entry = 
p15card->pin_cache[i];
-                       if (sc_pkcs15_compare_id(&entry->id, 
&pininfo->auth_id)) {
-                               memcpy(&entry->pin, pin, pinlen);
-                               entry->len = pinlen;
-                               entry->counter = 0;
-                               return;
-                       }
-                       
-               }
-       }
+       r = sc_pkcs15_allocate_object_content(obj, pin, pinlen);
+       if (r != SC_SUCCESS)   {
+               sc_debug(ctx, "Failed to allocate object content");
+               return;
+       } 
+
+       obj->usage_counter = 0;
+       sc_debug(ctx, "PIN(type:%X,reference:%X) cached", pininfo->type, 
pininfo->reference);
+
 }
+
 /* Validate the PIN code associated with an object */
-int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const 
sc_pkcs15_object_t *obj)
+int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, 
sc_pkcs15_object_t *obj)
 {
-       int r, i;
+       struct sc_context *ctx = p15card->card->ctx;
        sc_pkcs15_object_t *pin_obj;
        sc_pkcs15_pin_info_t *pin_info;
+       int r, i;
 
-       SC_FUNC_CALLED(p15card->card->ctx, 2);
+       SC_FUNC_CALLED(ctx, 2);
 
        if (!p15card->opts.use_pin_cache)
                return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
@@ -529,28 +524,38 @@
 
        r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj);
        if (r != SC_SUCCESS) {
-               sc_debug(p15card->card->ctx, "Could not find pin object for 
auth_id %s", sc_pkcs15_print_id(&obj->auth_id));
+               sc_debug(ctx, "Could not find pin object for auth_id %s", 
sc_pkcs15_print_id(&obj->auth_id));
                return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
        }
        
-       pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data;
-       for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++) {
-               sc_pkcs15_pincache_entry_t *entry = p15card->pin_cache[i];
-               if (sc_pkcs15_compare_id(&entry->id, &obj->auth_id)) {
-                       if (entry->counter >= p15card->opts.pin_cache_counter) {
-                               sc_mem_clear(entry->pin, entry->len);
-                               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
-                       }
-                       entry->counter++;
-                       return sc_pkcs15_verify_pin(p15card, pin_info,  
entry->pin, entry->len);
-               }
+       if (pin_obj->usage_counter >= p15card->opts.pin_cache_counter) {
+               sc_pkcs15_free_object_content(obj);
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
        }
-       return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+
+       if (!pin_obj->content.value || !pin_obj->content.len)
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+       /* FIXME: the usage counter should be incremented 
+        *      before or after (successeful ?) PIN verifying ? */
+       pin_obj->usage_counter++;
+
+       r = sc_pkcs15_verify_pin(p15card, pin_info, pin_obj->content.value, 
pin_obj->content.len);
+       if (r != SC_SUCCESS) {
+               sc_debug(ctx, "Verify PIN error %i", r);
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+       }
+
+       SC_FUNC_RETURN(ctx, 2, SC_SUCCESS);
 }
 
 void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card)
 {
-       int i;
-       for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++)
-               sc_mem_clear(p15card->pin_cache[i]->pin, 
p15card->pin_cache[i]->len); 
+       struct sc_pkcs15_object *objs[32];
+       int i, r;
+
+       SC_FUNC_CALLED(p15card->card->ctx, 2);
+       r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
+       for (i = 0; i < r; i++)
+               sc_pkcs15_free_object_content(objs[i]);
 }
+
Index: src/libopensc/pkcs15.c
===================================================================
--- src/libopensc/pkcs15.c      (révision 4012)
+++ src/libopensc/pkcs15.c      (copie de travail)
@@ -456,10 +456,6 @@
                        free(p15card->seInfo[i]);
                free(p15card->seInfo);
        }
-       for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++) {
-               sc_mem_clear(p15card->pin_cache[i]->pin, 
p15card->pin_cache[i]->len); 
-               free(p15card->pin_cache[i]);
-       }
        free(p15card);
 }
 
Index: src/libopensc/pkcs15.h
===================================================================
--- src/libopensc/pkcs15.h      (révision 4012)
+++ src/libopensc/pkcs15.h      (copie de travail)
@@ -326,6 +326,7 @@
        unsigned int flags;
        struct sc_pkcs15_id auth_id;
 
+       int usage_counter;
        int user_consent;
 
        /* Object type specific data */
@@ -380,13 +381,6 @@
 } sc_pkcs15_sec_env_info_t;
 
 typedef struct {
-       sc_pkcs15_id_t id;
-       u8 pin[SC_MAX_PIN_SIZE];
-       size_t len;
-       int counter;
-} sc_pkcs15_pincache_entry_t;
-
-typedef struct {
        unsigned int version;
        unsigned int flags;
        char *label;
@@ -425,7 +419,6 @@
 
        sc_pkcs15_sec_env_info_t **seInfo;
        size_t num_seInfo;
-       sc_pkcs15_pincache_entry_t *pin_cache[SC_PKCS15_MAX_PINS];
 
        unsigned int magic;
 
@@ -576,7 +569,7 @@
                                    struct sc_pkcs15_object **out);
 int sc_pkcs15_find_so_pin(struct sc_pkcs15_card *card,
                        struct sc_pkcs15_object **out);
-int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const 
sc_pkcs15_object_t *obj);
+int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, 
sc_pkcs15_object_t *obj);
 void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card);
 
 int sc_pkcs15_encode_dir(struct sc_context *ctx,
@@ -699,9 +692,9 @@
 /* Prepend 'parent' to 'child' in case 'child' is a relative path */
 int sc_pkcs15_make_absolute_path(const sc_path_t *parent, sc_path_t *child);
 
-/* Clean and free object value */
+/* Clean and free object content */
 void sc_pkcs15_free_object_content(struct sc_pkcs15_object *);
-/* Allocate and set object value */
+/* Allocate and set object content */
 int sc_pkcs15_allocate_object_content(struct sc_pkcs15_object *,
                const unsigned char *, size_t);
 
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to