Hi Martin,

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.

Regards,
Viktor.

PS : in attachement there is a draft of diff.


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

Index: src/pkcs15init/pkcs15-lib.c
===================================================================
--- src/pkcs15init/pkcs15-lib.c (révision 3999)
+++ src/pkcs15init/pkcs15-lib.c (copie de travail)
@@ -2679,8 +2679,8 @@
        sc_file_free(file);
 
        /* Set the SO PIN reference from card */
-       if ((r = set_so_pin_from_card(p15card, profile)) < 0)
-               return r;
+       r = set_so_pin_from_card(p15card, profile);
+       SC_TEST_RET(ctx, r, "Cannot set SOPIN from card");
 
        /* If the object is stored in a normal EF, try to delete the EF. */
        if (stored_in_ef) {
Index: src/libopensc/errors.c
===================================================================
--- src/libopensc/errors.c      (révision 3999)
+++ src/libopensc/errors.c      (copie de travail)
@@ -117,6 +117,8 @@
        const char **errors = NULL;
        int count = 0, err_base = 0;
        
+       if (!error)
+               return "No errors";
        if (error < 0)
                error = -error;
        if (error >= misc_base) {
Index: src/libopensc/pkcs15-pin.c
===================================================================
--- src/libopensc/pkcs15-pin.c  (révision 3999)
+++ src/libopensc/pkcs15-pin.c  (copie de travail)
@@ -464,6 +464,7 @@
        free(pin);
 }
 
+#if 0
 /* 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,
@@ -554,3 +555,98 @@
        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); 
 }
+
+#else
+
+/* 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)
+{
+       struct sc_context *ctx = p15card->card->ctx;
+       struct sc_pkcs15_object *obj = NULL;
+       int r;
+
+       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, "No PIN found with reference 0x%X", 
pininfo->reference);
+               return;
+       }
+               
+       /* Is it a user consent protecting PIN ? */
+       if (obj->user_consent) {
+               sc_debug(ctx, "Not caching user consent related PIN");
+               return;
+       }
+
+       sc_pkcs15_free_object_value(obj);
+
+       r = sc_pkcs15_allocate_object_value(obj, pin, pinlen);
+       if (r != SC_SUCCESS)   {
+               sc_debug(ctx, "Failed to allocate object value");
+               return;
+       } 
+
+       obj->usage_counter = 0;
+}
+
+/* Validate the PIN code associated with an object */
+int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, 
sc_pkcs15_object_t *obj)
+{
+       int r, i;
+       sc_pkcs15_object_t *pin_obj;
+       sc_pkcs15_pin_info_t *pin_info;
+
+       SC_FUNC_CALLED(p15card->card->ctx, 2);
+
+       if (!p15card->opts.use_pin_cache)
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+
+       if (obj->user_consent)
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+
+       if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+
+       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));
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+       }
+       
+       if (pin_obj->usage_counter >= p15card->opts.pin_cache_counter) {
+               sc_pkcs15_free_object_value(obj);
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+       }
+       
+       if (!pin_obj->der.value || !pin_obj->der.len)
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+
+       /* FIXME: should the usage counter be incremented after successeful PIN 
verifying ? */
+       pin_obj->usage_counter++;
+
+       r = sc_pkcs15_verify_pin(p15card, pin_info, pin_obj->der.value, 
pin_obj->der.len);
+       if (r != SC_SUCCESS) {
+               sc_debug(p15card->card->ctx, "Verify PIN error %i", r);
+               return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
+       }
+
+       SC_FUNC_RETURN(p15card->card->ctx, 2, SC_SUCCESS);
+}
+
+void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card)
+{
+       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_value(objs[i]);
+}
+#endif
Index: src/libopensc/pkcs15.c
===================================================================
--- src/libopensc/pkcs15.c      (révision 3999)
+++ src/libopensc/pkcs15.c      (copie de travail)
@@ -452,10 +452,12 @@
                        free(p15card->seInfo[i]);
                free(p15card->seInfo);
        }
+#if 0
        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]);
        }
+#endif
        free(p15card);
 }
 
@@ -1819,3 +1821,34 @@
                return SC_SUCCESS;
        return sc_concatenate_path(child, parent, child);
 }
+
+
+void sc_pkcs15_free_object_value(struct sc_pkcs15_object *obj)
+{
+       if (obj->der.value && obj->der.len)   {
+               sc_mem_clear(obj->der.value, obj->der.len);
+               free(obj->der.value);
+       }
+       obj->der.value = NULL;
+       obj->der.len = 0;
+}
+
+int sc_pkcs15_allocate_object_value(struct sc_pkcs15_object *obj, 
+               const unsigned char *value, size_t len)
+{
+       if (!obj)
+               return SC_ERROR_INVALID_ARGUMENTS;
+
+       sc_pkcs15_free_object_value(obj);
+
+       if (value && len)   {
+               obj->der.value = (unsigned char *)sc_mem_alloc_secure(len);
+               if (!obj->der.value)
+                       return SC_ERROR_OUT_OF_MEMORY;
+                                                                       
+               memcpy(obj->der.value, value, len);
+               obj->der.len = len;
+       }
+
+       return SC_SUCCESS;
+}
Index: src/libopensc/pkcs15.h
===================================================================
--- src/libopensc/pkcs15.h      (révision 3999)
+++ 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 */
@@ -379,12 +380,14 @@
        size_t                  aid_len;
 } sc_pkcs15_sec_env_info_t;
 
+#if 0
 typedef struct {
        sc_pkcs15_id_t id;
        u8 pin[SC_MAX_PIN_SIZE];
        size_t len;
        int counter;
 } sc_pkcs15_pincache_entry_t;
+#endif
 
 typedef struct {
        unsigned int version;
@@ -425,7 +428,9 @@
 
        sc_pkcs15_sec_env_info_t **seInfo;
        size_t num_seInfo;
+#if 0
        sc_pkcs15_pincache_entry_t *pin_cache[SC_PKCS15_MAX_PINS];
+#endif
 
        unsigned int magic;
 
@@ -576,7 +581,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,
@@ -696,10 +701,15 @@
 void sc_pkcs15_format_id(const char *id_in, struct sc_pkcs15_id *id_out);
 int sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out);
 void sc_der_copy(sc_pkcs15_der_t *, const sc_pkcs15_der_t *);
-void sc_der_clear(sc_pkcs15_der_t *);
 /* 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 */
+void sc_pkcs15_free_object_value(struct sc_pkcs15_object *obj);
+/* Allocate and set object value */
+int sc_pkcs15_allocate_object_value(struct sc_pkcs15_object *obj, 
+                       const unsigned char *value, size_t len);
+
 /* New object search API.
  * More complex, but also more powerful.
  */
Index: src/libopensc/asn1.c
===================================================================
--- src/libopensc/asn1.c        (révision 3999)
+++ src/libopensc/asn1.c        (copie de travail)
@@ -1520,11 +1520,3 @@
                memcpy(dst->value, src->value, src->len);
        }
 }
-
-void
-sc_der_clear(sc_pkcs15_der_t *der)
-{
-       if (der->value)
-               free(der->value);
-       memset(der, 0, sizeof(*der));
-}
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to