diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 09675a6e..a49d8b92 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -1299,8 +1299,8 @@ void sc_pkcs15_free_object(struct sc_pkcs15_object *obj) free(obj->data); } - if (obj->der.value) - free(obj->der.value); + sc_pkcs15_free_object_content(obj); + free(obj); } @@ -1475,14 +1475,6 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, } obj_len = p - oldp; - obj->der.value = (u8 *) malloc(obj_len); - if (obj->der.value == NULL) { - r = SC_ERROR_OUT_OF_MEMORY; - goto ret; - } - memcpy(obj->der.value, oldp, obj_len); - obj->der.len = obj_len; - obj->df = df; r = sc_pkcs15_add_object(p15card, obj); if (r) { @@ -1826,3 +1818,38 @@ int sc_pkcs15_make_absolute_path(const sc_path_t *parent, sc_path_t *child) return SC_SUCCESS; return sc_concatenate_path(child, parent, child); } + +void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj) +{ + if (obj->content.value && obj->content.len) { + sc_mem_clear(obj->content.value, obj->content.len); + free(obj->content.value); + } + obj->content.value = NULL; + obj->content.len = 0; +} + +int sc_pkcs15_allocate_object_content(struct sc_pkcs15_object *obj, + const unsigned char *value, size_t len) +{ + if (!obj) + return SC_ERROR_INVALID_ARGUMENTS; + + if (obj->content.value == value && obj->content.len >= len) { + obj->content.len = len; + return SC_SUCCESS; + } + + sc_pkcs15_free_object_content(obj); + + if (value && len) { + obj->content.value = (unsigned char *)sc_mem_alloc_secure(len); + if (!obj->content.value) + return SC_ERROR_OUT_OF_MEMORY; + + memcpy(obj->content.value, value, len); + obj->content.len = len; + } + return SC_SUCCESS; +} + diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 3003be3d..233cfa9a 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -334,7 +334,7 @@ struct sc_pkcs15_object { struct sc_pkcs15_df *df; /* can be NULL, if object is 'floating' */ struct sc_pkcs15_object *next, *prev; /* used only internally */ - struct sc_pkcs15_der der; + struct sc_pkcs15_der content; }; typedef struct sc_pkcs15_object sc_pkcs15_object_t; @@ -699,6 +699,12 @@ void sc_der_copy(sc_pkcs15_der_t *, const 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_content(struct sc_pkcs15_object *); +/* Allocate and set object value */ +int sc_pkcs15_allocate_object_content(struct sc_pkcs15_object *, + const unsigned char *, size_t); + /* New object search API. * More complex, but also more powerful. */