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