Support for deleting pkcs15 objects

classic Classic list List threaded Threaded
30 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Tarasov Viktor
Nils Larsch wrote:

> Hi Viktor,
>
> Tarasov Viktor wrote:
> ...
>
>>>> I will prepare patch.
>>>
>>>
>>>
>>> hopefully against the current svn trunk ;-)
>>
>>
>>
>> Here it is.
>
>
> Hmm, your patch changes the "old" style api. I don't really like
> having two different APIs for the same thing (and actually I want
> to remove the old style API in some future release). So what changes
> in the new style api are necessary so it can be used in
> pkcs15-oberthur.c ?

Change the 'struct sc_card' type arguments of 'struct
sc_pkcs15init_operations'
entries for the 'struct sc_pkcs15_card' type.
Implement some card-specific call in the new API of
sc_pkcs15init_store_data() (something like old style 'new_file').


The main idea is that the card-specific part should get know the current
PKCS#15 card's structure,
and that the card-specific side should have the possibility to intervene
into the maximum of the default behaviors.


When I noticed a new style API, I tried to migrate the oberthur driver
to the new API,
but after a while, I abandoned it.  It seems to me, that the new API
is more restrictive then the old one.
For example, in new API of sc_pkcs15init_store_data() there is no
card-specific call.
(That's why I still use the old API. For me, it's easier to separate the
object ID and file index with
the old style API then with a new one.).


One question about the profile procedures.
Now, the rule of the template instantiating is defined in profile procedure
(sc_profile_instantiate_template()).
Once more, IMHO, it's too restrictive.
I guess that these rules has to be defined in the card profile or in the
card-specific pkcs15init,
with, obviously, some default procedures.
(Personally, I would prefere to see it in the card profile.)

Kind wishes,
Viktor.

> Cheers,
> Nils
>

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Stef Hoeben
In reply to this post by Tarasov Viktor
Hi,

here a 2nd proposal for deleting pkcs15 objects: now with
a delete_object() sc_pkcs15init_operation.
(And most functionality put in pkcs15-init.c iso pkcs15-lib.c)

So each pkcs15init card driver who wants to add support
for deleting objects has to implement this function.

E.g. for the Setcos 4.4.1 card, this amounts to:

Index: pkcs15-setcos.c
===================================================================
--- pkcs15-setcos.c     (revision 2495)
+++ pkcs15-setcos.c     (working copy)
@@ -566,6 +566,13 @@
        return pin_info.tries_left;
 }

+static int setcos_delete_object(struct sc_profile *profile, struct
sc_card *card,
+       unsigned int type, const void *data, const sc_path_t *path)
+{
+       /* For Setcos, all objects are files that can be deleted in any
order */
+       return sc_pkcs15init_delete_by_path(profile, card, path);
+}
+
 static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = {
        setcos_erase_card,
        NULL,                           /* init_card     */
@@ -584,7 +591,8 @@
        NULL,                           /* old style api */
        setcos_new_key,
        setcos_new_file,
-       setcos_old_generate_key
+       setcos_old_generate_key,
+       setcos_delete_object
 };

 struct sc_pkcs15init_operations *

Cheers,
Stef


Index: pkcs15-init.c
===================================================================
--- pkcs15-init.c (revision 2493)
+++ pkcs15-init.c (working copy)
@@ -65,6 +65,7 @@
 static int open_reader_and_card(int);
 static int do_assert_pristine(sc_card_t *);
 static int do_erase(sc_card_t *, struct sc_profile *);
+static int do_delete_objects(struct sc_profile *, unsigned int opt_delete_flags);
 static int do_init_app(struct sc_profile *);
 static int do_store_pin(struct sc_profile *);
 static int do_generate_key(struct sc_profile *, const char *);
@@ -135,6 +136,7 @@
  { "store-public-key", required_argument, 0, OPT_PUBKEY },
  { "store-certificate", required_argument, 0, 'X' },
  { "store-data", required_argument, 0, 'W' },
+ { "delete-objects", required_argument, 0, 'D' },
 
  { "reader", required_argument, 0, 'r' },
  { "pin", required_argument, 0, OPT_PIN1 },
@@ -185,6 +187,7 @@
  "Store public key",
  "Store an X.509 certificate",
  "Store a data object",
+ "Delete object(s) (use \"help\" for more information)",
 
  "Specify which reader to use",
  "Specify PIN",
@@ -236,6 +239,7 @@
  ACTION_STORE_CERT,
  ACTION_STORE_DATA,
  ACTION_FINALIZE_CARD,
+ ACTION_DELETE_OBJECTS,
 
  ACTION_MAX
 };
@@ -250,7 +254,8 @@
  "store public key",
  "store certificate",
  "store data object",
- "finalizing card"
+ "finalizing card",
+ "delete object(s)"
 };
 
 #define MAX_CERTS 4
@@ -263,6 +268,14 @@
  size_t len;
 };
 
+#define SC_PKCS15INIT_DEL_DATA 0x8000
+
+/* Flags for do_delete_crypto_objects() */
+#define SC_PKCS15INIT_DEL_PRKEY 1
+#define SC_PKCS15INIT_DEL_PUBKEY 2
+#define SC_PKCS15INIT_DEL_CERT 4
+#define SC_PKCS15INIT_DEL_CHAIN (8 | 4)
+
 static sc_context_t * ctx = NULL;
 static sc_card_t * card = NULL;
 static struct sc_pkcs15_card * p15card = NULL;
@@ -293,6 +306,7 @@
 static char * opt_outkey = 0;
 static char * opt_application_id = 0;
 static unsigned int opt_x509_usage = 0;
+static unsigned int opt_delete_flags = 0;
 static int ignore_cmdline_pins = 0;
 static struct secret opt_secrets[MAX_SECRETS];
 static unsigned int opt_secret_count;
@@ -404,6 +418,9 @@
  case ACTION_STORE_DATA:
  r = do_store_data_object(profile);
  break;
+ case ACTION_DELETE_OBJECTS:
+ r = do_delete_objects(profile, opt_delete_flags);
+ break;
  case ACTION_GENERATE_KEY:
  r = do_generate_key(profile, opt_newkey);
  break;
@@ -922,6 +939,172 @@
  return r;
 }
 
+static inline int cert_is_root(sc_pkcs15_cert_t *c)
+{
+ return (c->subject_len == c->issuer_len) &&
+ (memcmp(c->subject, c->issuer, c->subject_len) == 0);
+}
+
+/* Check if the cert has a 'sibling' and return it's parent cert.
+ * Should be made more effcicient for long chains by caching the certs.
+ */
+static int get_cert_info(sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *certobj,
+ int *has_sibling, int *stop, sc_pkcs15_object_t **issuercert)
+{
+ sc_pkcs15_cert_t *cert = NULL;
+ sc_pkcs15_object_t *otherobj;
+ sc_pkcs15_cert_t *othercert = NULL;
+ int r;
+
+ *issuercert = NULL;
+ *has_sibling = 0;
+ *stop = 0;
+
+ r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) certobj->data, &cert);
+ if (r < 0)
+ return r;
+
+ if (cert_is_root(cert)) {
+ *stop = 1; /* root -> no parent and hence no siblings */
+ goto done;
+ }
+ for (otherobj = p15card->obj_list; otherobj != NULL; otherobj = otherobj->next) {
+ if ((otherobj == certobj) ||
+ !((otherobj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT))
+ continue;
+ if (othercert)
+ sc_pkcs15_free_certificate(othercert);
+ r = sc_pkcs15_read_certificate(p15card, (sc_pkcs15_cert_info_t *) otherobj->data, &othercert);
+ if (r < 0)
+ goto done;
+ if ((cert->issuer_len == othercert->subject_len) &&
+ (memcmp(cert->issuer, othercert->subject, cert->issuer_len) == 0)) {
+ /* parent cert found */
+ *issuercert = otherobj;
+ *stop = cert_is_root(othercert);
+ }
+ else if (!cert_is_root(othercert) && (cert->issuer_len == othercert->issuer_len) &&
+ (memcmp(cert->issuer, othercert->issuer, cert->issuer_len) == 0)) {
+ *has_sibling = 1;
+ break;
+ }
+ }
+
+done:
+ if (cert)
+ sc_pkcs15_free_certificate(cert);
+ if (othercert)
+ sc_pkcs15_free_certificate(othercert);
+
+ return r;
+}
+
+/* Delete object(s) by ID. The 'which' param can be any combination of
+ * SC_PKCS15INIT_DEL_PRKEY, SC_PKCS15INIT_DEL_PUBKEY, SC_PKCS15INIT_DEL_CERT
+ * and SC_PKCS15INIT_DEL_CHAIN. In the last case, every cert in the chain is
+ * deleted, starting with the cert with ID 'id' and untill a CA cert is
+ * reached that certified other remaining certs on the card.
+ */
+static int do_delete_crypto_objects(sc_pkcs15_card_t *p15card,
+ sc_profile_t *profile,
+ const sc_pkcs15_id_t id,
+ unsigned int which)
+{
+ sc_pkcs15_object_t *objs[10]; /* 1 priv + 1 pub + chain of at most 8 certs, should be enough */
+ sc_context_t *ctx = p15card->card->ctx;
+ int i, r = 0, count = 0, del_cert = 0;
+
+ if (which & SC_PKCS15INIT_DEL_PRKEY) {
+    if (sc_pkcs15_find_prkey_by_id(p15card, &id, &objs[count]) != 0)
+ sc_debug(ctx, "NOTE: couldn't find privkey %s to delete\n", sc_pkcs15_print_id(&id));
+ else
+ count++;
+ }
+
+ if (which & SC_PKCS15INIT_DEL_PUBKEY) {
+    if (sc_pkcs15_find_pubkey_by_id(p15card, &id, &objs[count]) != 0)
+ sc_debug(ctx, "NOTE: couldn't find pubkey %s to delete\n", sc_pkcs15_print_id(&id));
+ else
+ count++;
+ }
+
+ if (which & SC_PKCS15INIT_DEL_CERT) {
+    if (sc_pkcs15_find_cert_by_id(p15card, &id, &objs[count]) != 0)
+ sc_debug(ctx, "NOTE: couldn't find cert %s to delete\n", sc_pkcs15_print_id(&id));
+ else {
+ count++;
+ del_cert = 1;
+ }
+ }
+
+ if (del_cert && ((which & SC_PKCS15INIT_DEL_CHAIN) == SC_PKCS15INIT_DEL_CHAIN)) {
+ /* Get the cert chain, stop if there's a CA that is the issuer of
+ * other certs on this card */
+ int has_sibling; /* siblings: certs having the same issuer */
+ int stop;
+ for( ; count < 10 ; count++) {
+ r = get_cert_info(p15card, objs[count - 1], &has_sibling, &stop, &objs[count]);
+ if (r < 0)
+ sc_error(ctx, "get_cert_info() failed: %s\n", sc_strerror(r));
+ else if (has_sibling)
+ sc_debug(ctx, "Chain deletion stops with cert %s\n", sc_pkcs15_print_id(
+ &((sc_pkcs15_cert_info_t *) objs[count - 1]->data)->id));
+ else if ((objs[count] != NULL))
+ count++;
+ if (stop || (objs[count] == NULL))
+ break;
+ }
+ if (r < 0)
+ count = -1; /* Something wrong -> don't delete anything */
+ }
+
+ for (i = 0; i < count; i++) {
+ r = sc_pkcs15init_delete_object(p15card, profile, objs[i]);
+ if (r < 0) {
+ sc_error(ctx, "Failed to delete object %d: %s\n", i, sc_strerror(r));
+ break;
+ }
+ }
+
+ return r < 0 ? r : count;
+}
+
+static int
+do_delete_objects(struct sc_profile *profile, unsigned int opt_delete_flags)
+{
+ int r, count = 0;
+
+ if (opt_delete_flags & SC_PKCS15INIT_DEL_DATA) {
+ struct sc_object_id app_oid;
+ sc_pkcs15_object_t *obj;
+ if (opt_application_id == NULL)
+ fatal("Specify the --application-id for the data object to be deleted\n");
+ parse_application_id(&app_oid, opt_application_id);
+
+ r = sc_pkcs15_find_data_object_by_app_oid(p15card, &app_oid, &obj);
+ if (r >= 0) {
+ r = sc_pkcs15init_delete_object(p15card, profile, obj);
+ if (r >= 0)
+ count++;
+ }
+ }
+
+ if (opt_delete_flags & (SC_PKCS15INIT_DEL_PRKEY | SC_PKCS15INIT_DEL_PUBKEY | SC_PKCS15INIT_DEL_CHAIN)) {
+ sc_pkcs15_id_t id;
+ if (opt_objectid == NULL)
+ fatal("Specify the --id for key(s) or cert(s) to be deleted\n");
+ sc_pkcs15_format_id(opt_objectid, &id);
+
+ r = do_delete_crypto_objects(p15card, profile, id, opt_delete_flags);
+ if (r >= 0)
+ count += r;
+ }
+
+ printf("Deleted %d objects\n", count);
+
+ return r;
+}
+
 /*
  * Generate a new private key
  */
@@ -1780,6 +1963,56 @@
  return 0;
 }
 
+static unsigned int
+parse_delete_flags(const char *list)
+{
+ unsigned int res = 0;
+ static struct {
+ const char *name;
+ unsigned int flag;
+ } del_flags[] = {
+ {"privkey", SC_PKCS15INIT_DEL_PRKEY},
+ {"pubkey", SC_PKCS15INIT_DEL_PUBKEY},
+ {"cert", SC_PKCS15INIT_DEL_CERT},
+ {"chain", SC_PKCS15INIT_DEL_CHAIN},
+ {"data", SC_PKCS15INIT_DEL_DATA},
+ {NULL, 0}
+ };
+
+ while (1) {
+ int len, n, match = 0;
+
+ while (*list == ',')
+ list++;
+ if (!*list)
+ break;
+ len = strcspn(list, ",");
+ if (len == 4 && !strncasecmp(list, "help", 4)) {
+ printf("\nDelete arguments: a comma-separated list containing any of the following:\n");
+ printf("  privkey,pubkey,cert,chain,data\n");
+ printf("When \"data\" is specified, an --application-id must also be specified,\n");
+ printf("  in the other cases an \"--id\" must also be specified\n");
+ printf("When \"chain\" is specified, the certificate chain starting with the cert\n");
+ printf("  with specified ID will be deleted, untill there's a CA cert that certifies\n");
+ printf("  another cert on the card\n");
+ exit(0);
+ }
+ for (n = 0; del_flags[n].name; n++) {
+ if (!strncasecmp(del_flags[n].name, list, len)) {
+ res |= del_flags[n].flag;
+ break;
+ }
+ }
+ if (del_flags[n].name == NULL) {
+ fprintf(stderr, "Unknown argument for --delete_objects: %.*s\n", len, list);
+ exit(0);
+ }
+ list += len;
+ }
+
+ return res;
+}
+
 /*
  * Parse X.509 key usage list
  */
@@ -1890,6 +2123,10 @@
  this_action = ACTION_STORE_DATA;
  opt_infile = optarg;
  break;
+ case 'D':
+ this_action = ACTION_DELETE_OBJECTS;
+ opt_delete_flags = parse_delete_flags(optarg);
+ break;
  case 'v':
  verbose++;
  break;


Index: pkcs15-lib.c
===================================================================
--- pkcs15-lib.c (revision 2496)
+++ pkcs15-lib.c (working copy)
@@ -134,6 +134,8 @@
 static int sc_pkcs15init_parse_info(sc_card_t *, const u8 *, size_t, sc_profile_t *);
 static int sc_pkcs15init_write_info(sc_card_t *card, sc_profile_t *,
  sc_pkcs15_object_t *pin_obj);
+static int get_cert_info(sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *certobj,
+ int *has_sibling, int *stop, sc_pkcs15_object_t **issuercert);
 
 static struct profile_operations {
  const char *name;
@@ -447,6 +449,50 @@
  return r;
 }
 
+int sc_pkcs15init_delete_by_path(struct sc_profile *profile,
+ struct sc_card *card, const sc_path_t *file_path)
+{
+ sc_file_t *parent, *file;
+ sc_path_t path;
+ int r;
+
+ if (file_path->len >= 2) {
+ /* Select the parent DF */
+ path = *file_path;
+ path.len -= 2;
+ r = sc_select_file(card, &path, &parent);
+ if (r < 0)
+ return r;
+
+ r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
+ sc_file_free(parent);
+ if (r < 0)
+ return r;
+ }
+
+ /* Select the file itself */
+ path = *file_path;
+ r = sc_select_file(card, &path, &file);
+ if (r < 0)
+ return r;
+
+ r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_ERASE);
+ sc_file_free(file);
+ if (r < 0)
+ return r;
+
+ memset(&path, 0, sizeof(path));
+ path.type = SC_PATH_TYPE_FILE_ID;
+ path.value[0] = file_path->value[file_path->len - 2];
+ path.value[1] = file_path->value[file_path->len - 1];
+ path.len = 2;
+
+ card->ctx->suppress_errors++;
+ r = sc_delete_file(card, &path);
+ card->ctx->suppress_errors--;
+ return r;
+}
+
 /*
  * Try to delete a file (and, in the DF case, its contents).
  * Note that this will not work if a pkcs#15 file's ERASE AC
@@ -505,13 +551,15 @@
  if (r < 0)
  return r;
 
+ r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
+ if (r < 0) {
+ sc_file_free(parent);
+ return r;
+ }
  r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
  sc_file_free(parent);
  if (r < 0)
  return r;
- r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
- if (r < 0)
- return r;
 
  memset(&path, 0, sizeof(path));
  path.type = SC_PATH_TYPE_FILE_ID;
@@ -2478,6 +2526,57 @@
  return r < 0 ? r : 0;
 }
 
+int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
+ sc_profile_t *profile, sc_pkcs15_object_t *obj)
+{
+ sc_path_t path;
+ struct sc_pkcs15_df *df;
+ int r;
+
+ if (profile->ops->delete_object == NULL)
+ return SC_ERROR_NOT_SUPPORTED;
+
+ switch(obj->type & SC_PKCS15_TYPE_CLASS_MASK)
+ {
+ case SC_PKCS15_TYPE_PUBKEY:
+ path = ((sc_pkcs15_pubkey_info_t *)obj->data)->path;
+ break;
+ case SC_PKCS15_TYPE_PRKEY:
+ path = ((sc_pkcs15_prkey_info_t *)obj->data)->path;
+ break;
+ case SC_PKCS15_TYPE_CERT:
+ path = ((sc_pkcs15_cert_info_t *)obj->data)->path;
+ break;
+ case SC_PKCS15_TYPE_DATA_OBJECT:
+ path = ((sc_pkcs15_data_info_t *)obj->data)->path;
+ break;
+ default:
+ return SC_ERROR_NOT_SUPPORTED;
+ }
+
+ /* Set the SO PIN reference from card */
+ if ((r = set_so_pin_from_card(p15card, profile)) < 0)
+ return r;
+
+ r = profile->ops->delete_object(profile, p15card->card,
+ obj->type, obj->data, &path);
+ if (r < 0) {
+ sc_error(p15card->card->ctx, "ops->delete_object() failed: %d", r);
+ return r;
+ }
+
+ /* Get the DF we're part of. If there's no DF, fine, we haven't
+ * been added yet. */
+ if ((df = obj->df) == NULL)
+ return 0;
+
+ /* Unlink the object and update the DF */
+ sc_pkcs15_remove_object(p15card, obj);
+ r = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
+
+ return r;
+}
+
 /*
  * PIN verification
  */
Index: pkcs15-init.h
===================================================================
--- pkcs15-init.h (revision 2495)
+++ pkcs15-init.h (working copy)
@@ -159,6 +159,11 @@
  sc_pkcs15_pubkey_t *pubkey_res,
  struct sc_pkcs15_prkey_info *);
 
+ /*
+ * Delete object
+ */
+ int (*delete_object)(struct sc_profile *, struct sc_card *,
+ unsigned int type, const void *data, const sc_path_t *path);
 };
 
 /* Do not change these or reorder these */
@@ -317,6 +322,9 @@
  int new_attrib_type,
  void *new_value,
  int new_len);
+extern int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
+ sc_profile_t *profile,
+ sc_pkcs15_object_t *obj);
 
 extern int sc_pkcs15init_create_file(struct sc_profile *,
  struct sc_card *, struct sc_file *);
@@ -344,6 +352,8 @@
  const u8 *, size_t);
 extern int sc_pkcs15init_verify_key(struct sc_profile *, struct sc_card *,
  sc_file_t *,  unsigned int, unsigned int);
+extern int sc_pkcs15init_delete_by_path(struct sc_profile *,
+ struct sc_card *, const sc_path_t *path);
 
 /* Erasing the card structure via rm -rf */
 extern int sc_pkcs15init_erase_card_recursively(struct sc_card *,


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Nils Larsch
Stef Hoeben wrote:
> Hi,
>
> here a 2nd proposal for deleting pkcs15 objects: now with
> a delete_object() sc_pkcs15init_operation.
> (And most functionality put in pkcs15-init.c iso pkcs15-lib.c)
>
> So each pkcs15init card driver who wants to add support
> for deleting objects has to implement this function.

perhaps it would be good idea to add a
        NULL /* delete_object */
to the initialization of the other card drivers, so it's
obvious that this functionality is missing

...

> Index: pkcs15-lib.c
> ===================================================================
> --- pkcs15-lib.c (revision 2496)
> +++ pkcs15-lib.c (working copy)
> @@ -134,6 +134,8 @@
>  static int sc_pkcs15init_parse_info(sc_card_t *, const u8 *, size_t, sc_profile_t *);
>  static int sc_pkcs15init_write_info(sc_card_t *card, sc_profile_t *,
>   sc_pkcs15_object_t *pin_obj);
> +static int get_cert_info(sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *certobj,
> + int *has_sibling, int *stop, sc_pkcs15_object_t **issuercert);

the function get_cert_info isn't defined/used anywhere

>  
>  static struct profile_operations {
>   const char *name;
> @@ -447,6 +449,50 @@
>   return r;
>  }
>  
> +int sc_pkcs15init_delete_by_path(struct sc_profile *profile,
> + struct sc_card *card, const sc_path_t *file_path)
> +{
> + sc_file_t *parent, *file;
> + sc_path_t path;
> + int r;
> +
> + if (file_path->len >= 2) {
> + /* Select the parent DF */
> + path = *file_path;
> + path.len -= 2;
> + r = sc_select_file(card, &path, &parent);
> + if (r < 0)
> + return r;
> +
> + r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
> + sc_file_free(parent);
> + if (r < 0)
> + return r;
> + }
> +
> + /* Select the file itself */
> + path = *file_path;
> + r = sc_select_file(card, &path, &file);
> + if (r < 0)
> + return r;
> +
> + r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_ERASE);
> + sc_file_free(file);
> + if (r < 0)
> + return r;
> +
> + memset(&path, 0, sizeof(path));
> + path.type = SC_PATH_TYPE_FILE_ID;
> + path.value[0] = file_path->value[file_path->len - 2];
> + path.value[1] = file_path->value[file_path->len - 1];
> + path.len = 2;
> +
> + card->ctx->suppress_errors++;
> + r = sc_delete_file(card, &path);
> + card->ctx->suppress_errors--;
> + return r;

why are the errors in sc_delete_file suppressed here ?

> +}
> +
>  /*
>   * Try to delete a file (and, in the DF case, its contents).
>   * Note that this will not work if a pkcs#15 file's ERASE AC
> @@ -505,13 +551,15 @@
>   if (r < 0)
>   return r;
>  
> + r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
> + if (r < 0) {
> + sc_file_free(parent);
> + return r;
> + }
>   r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
>   sc_file_free(parent);
>   if (r < 0)
>   return r;
> - r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
> - if (r < 0)
> - return r;
>  
>   memset(&path, 0, sizeof(path));
>   path.type = SC_PATH_TYPE_FILE_ID;
> @@ -2478,6 +2526,57 @@
>   return r < 0 ? r : 0;
>  }

perhaps I'm bit too tired, but I don't really understand what's
the reason for changing the order here (and what's the
sc_pkcs15init_authenticate(..., df, SC_AC_OP_ERASE) is good for).

Cheers,
Nils
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Stef Hoeben
Nils Larsch wrote:

> Stef Hoeben wrote:
>
>> Hi,
>>
>> here a 2nd proposal for deleting pkcs15 objects: now with
>> a delete_object() sc_pkcs15init_operation.
>> (And most functionality put in pkcs15-init.c iso pkcs15-lib.c)
>>
>> So each pkcs15init card driver who wants to add support
>> for deleting objects has to implement this function.
>
>
> perhaps it would be good idea to add a
>     NULL        /* delete_object */
> to the initialization of the other card drivers, so it's
> obvious that this functionality is missing

ACK

>
> ...
>
>> Index: pkcs15-lib.c
>> ===================================================================
>> --- pkcs15-lib.c    (revision 2496)
>> +++ pkcs15-lib.c    (working copy)
>> @@ -134,6 +134,8 @@
>>  static int    sc_pkcs15init_parse_info(sc_card_t *, const u8 *,
>> size_t, sc_profile_t *);
>>  static int    sc_pkcs15init_write_info(sc_card_t *card, sc_profile_t *,
>>              sc_pkcs15_object_t *pin_obj);
>> +static int    get_cert_info(sc_pkcs15_card_t *p15card,
>> sc_pkcs15_object_t *certobj,
>> +            int *has_sibling, int *stop, sc_pkcs15_object_t
>> **issuercert);
>
>
> the function get_cert_info isn't defined/used anywhere

Ah, sorry, forgotten to move it to pkcs15-init.c as well..

>
>>  
>>  static struct profile_operations {
>>      const char *name;
>> @@ -447,6 +449,50 @@
>>      return r;
>>  }
>>  
>> +int sc_pkcs15init_delete_by_path(struct sc_profile *profile,
>> +        struct sc_card *card, const sc_path_t *file_path)
>> +{
>> +    sc_file_t *parent, *file;
>> +    sc_path_t path;
>> +    int r;
>> +
>> +    if (file_path->len >= 2) {
>> +        /* Select the parent DF */
>> +        path = *file_path;
>> +        path.len -= 2;
>> +        r = sc_select_file(card, &path, &parent);
>> +        if (r < 0)
>> +            return r;
>> +
>> +        r = sc_pkcs15init_authenticate(profile, card, parent,
>> SC_AC_OP_DELETE);
>> +        sc_file_free(parent);
>> +        if (r < 0)
>> +            return r;
>> +    }
>> +
>> +    /* Select the file itself */
>> +    path = *file_path;
>> +    r = sc_select_file(card, &path, &file);
>> +    if (r < 0)
>> +        return r;
>> +
>> +    r = sc_pkcs15init_authenticate(profile, card, file,
>> SC_AC_OP_ERASE);
>> +    sc_file_free(file);
>> +    if (r < 0) +        return r;
>> +
>> +    memset(&path, 0, sizeof(path));
>> +    path.type = SC_PATH_TYPE_FILE_ID;
>> +    path.value[0] = file_path->value[file_path->len - 2];
>> +    path.value[1] = file_path->value[file_path->len - 1];
>> +    path.len = 2;
>> +
>> +    card->ctx->suppress_errors++;
>> +    r = sc_delete_file(card, &path);
>> +    card->ctx->suppress_errors--;
>> +    return r;
>
>
> why are the errors in sc_delete_file suppressed here ?

It's a copy-paste from other code in pkcs15-lib.c.
But indeed, it's better to remove it..

>
>> +}
>> +
>>  /*
>>   * Try to delete a file (and, in the DF case, its contents).
>>   * Note that this will not work if a pkcs#15 file's ERASE AC
>> @@ -505,13 +551,15 @@
>>      if (r < 0)
>>          return r;
>>  
>> +    r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
>> +    if (r < 0) {
>> +        sc_file_free(parent);
>> +        return r;
>> +    }
>>      r = sc_pkcs15init_authenticate(profile, card, parent,
>> SC_AC_OP_DELETE);
>>      sc_file_free(parent);
>>      if (r < 0)
>>          return r;
>> -    r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
>> -    if (r < 0)
>> -        return r;
>>  
>>      memset(&path, 0, sizeof(path));
>>      path.type = SC_PATH_TYPE_FILE_ID;
>> @@ -2478,6 +2526,57 @@
>>      return r < 0 ? r : 0;
>>  }
>
>
> perhaps I'm bit too tired, but I don't really understand what's
> the reason for changing the order here (and what's the
> sc_pkcs15init_authenticate(..., df, SC_AC_OP_ERASE) is good for).

Ouch, again a copy-paste: should be SC_AC_OP_DELETE.
So both the DELETE AC of parent DF and of the file itself need to be
satisfied (though ISO7816-9 isn't too clear about this, IMHO).

The reason I changed the order: because sc_pkcs15init_authenticate() can
now select the EF/DF in question (old issue -> better to looking at the info
in the file then in the profile); but in order to do an
sc_delete_file(), the
parent has to be selected.

Thx,
Stef

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Nils Larsch
Stef Hoeben wrote:
...

>>> +    card->ctx->suppress_errors++;
>>> +    r = sc_delete_file(card, &path);
>>> +    card->ctx->suppress_errors--;
>>> +    return r;
>>
>>
>>
>> why are the errors in sc_delete_file suppressed here ?
>
>
> It's a copy-paste from other code in pkcs15-lib.c.

yep I know, but I didn't understand why it is used there as well
(and as you re-use this code ...)

>>> +}
>>> +
>>>  /*
>>>   * Try to delete a file (and, in the DF case, its contents).
>>>   * Note that this will not work if a pkcs#15 file's ERASE AC
>>> @@ -505,13 +551,15 @@
>>>      if (r < 0)
>>>          return r;
>>>  
>>> +    r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
>>> +    if (r < 0) {
>>> +        sc_file_free(parent);
>>> +        return r;
>>> +    }
>>>      r = sc_pkcs15init_authenticate(profile, card, parent,
>>> SC_AC_OP_DELETE);
>>>      sc_file_free(parent);
>>>      if (r < 0)
>>>          return r;
>>> -    r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
>>> -    if (r < 0)
>>> -        return r;
>>>  
>>>      memset(&path, 0, sizeof(path));
>>>      path.type = SC_PATH_TYPE_FILE_ID;
>>> @@ -2478,6 +2526,57 @@
>>>      return r < 0 ? r : 0;
>>>  }
>>
>>
>>
>> perhaps I'm bit too tired, but I don't really understand what's
>> the reason for changing the order here (and what's the
>> sc_pkcs15init_authenticate(..., df, SC_AC_OP_ERASE) is good for).
>
>
> Ouch, again a copy-paste: should be SC_AC_OP_DELETE.
> So both the DELETE AC of parent DF and of the file itself need to be
> satisfied (though ISO7816-9 isn't too clear about this, IMHO).

I don't have iso 7816-9 at hand right now, but it looks rather strange
(at least for someone normally using unix like boxes). What is the
DELETE right in the parent DF good for in this case ? ....

Nils

PS: You should set the sc_profile::dirty flag to 1 in
     sc_pkcs15init_delete_object, so the last update field (in case it's
     used) is updated.

PPS: What about a short CHANGES entry ;-)
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Stef Hoeben
Nils Larsch wrote:

> Stef Hoeben wrote:
> ...
>
>>>> +    card->ctx->suppress_errors++;
>>>> +    r = sc_delete_file(card, &path);
>>>> +    card->ctx->suppress_errors--;
>>>> +    return r;
>>>
>>>
>>>
>>>
>>> why are the errors in sc_delete_file suppressed here ?
>>
>>
>>
>> It's a copy-paste from other code in pkcs15-lib.c.
>
>
> yep I know, but I didn't understand why it is used there as well
> (and as you re-use this code ...)

Not sure, but I guess that other code is only used in case something
went wrong; so you try to undo it but are not sure that the file has
extually been created or not.
(So it's different from the delete() case where we indeed shouldn't
suppress the errors.)

>
>>>> +}
>>>> +
>>>>  /*
>>>>   * Try to delete a file (and, in the DF case, its contents).
>>>>   * Note that this will not work if a pkcs#15 file's ERASE AC
>>>> @@ -505,13 +551,15 @@
>>>>      if (r < 0)
>>>>          return r;
>>>>  
>>>> +    r = sc_pkcs15init_authenticate(profile, card, df,
>>>> SC_AC_OP_ERASE);
>>>> +    if (r < 0) {
>>>> +        sc_file_free(parent);
>>>> +        return r;
>>>> +    }
>>>>      r = sc_pkcs15init_authenticate(profile, card, parent,
>>>> SC_AC_OP_DELETE);
>>>>      sc_file_free(parent);
>>>>      if (r < 0)
>>>>          return r;
>>>> -    r = sc_pkcs15init_authenticate(profile, card, df,
>>>> SC_AC_OP_ERASE);
>>>> -    if (r < 0)
>>>> -        return r;
>>>>  
>>>>      memset(&path, 0, sizeof(path));
>>>>      path.type = SC_PATH_TYPE_FILE_ID;
>>>> @@ -2478,6 +2526,57 @@
>>>>      return r < 0 ? r : 0;
>>>>  }
>>>
>>>
>>>
>>>
>>> perhaps I'm bit too tired, but I don't really understand what's
>>> the reason for changing the order here (and what's the
>>> sc_pkcs15init_authenticate(..., df, SC_AC_OP_ERASE) is good for).
>>
>>
>>
>> Ouch, again a copy-paste: should be SC_AC_OP_DELETE.
>> So both the DELETE AC of parent DF and of the file itself need to be
>> satisfied (though ISO7816-9 isn't too clear about this, IMHO).
>
>
> I don't have iso 7816-9 at hand right now, but it looks rather strange
> (at least for someone normally using unix like boxes). What is the
> DELETE right in the parent DF good for in this case ? ....

It's the right to delete children in that DF.
Comming to think of it, deleting is a pretty sensitive thing (e.g. deleting
a PIN file and then re-creating it...) so in that sense it's logical
that you
can prevent deleting on 2 levels (the EF/DF itself and the parent DF).

>
> PS: You should set the sc_profile::dirty flag to 1 in
>     sc_pkcs15init_delete_object, so the last update field (in case it's
>     used) is updated.

Okay

>
> PPS: What about a short CHANGES entry ;-)

Fine. Where should I put it? Some file in SVN or in the Wiki?

Cheers,
Stef

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Stef Hoeben
Stef Hoeben wrote:

> Nils Larsch wrote:
>
>> Stef Hoeben wrote:
>> ...
>>
>>>>> +    card->ctx->suppress_errors++;
>>>>> +    r = sc_delete_file(card, &path);
>>>>> +    card->ctx->suppress_errors--;
>>>>> +    return r;
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> why are the errors in sc_delete_file suppressed here ?
>>>
>>>
>>>
>>>
>>> It's a copy-paste from other code in pkcs15-lib.c.
>>
>>
>>
>> yep I know, but I didn't understand why it is used there as well
>> (and as you re-use this code ...)
>
>
> Not sure, but I guess that other code is only used in case something
> went wrong; so you try to undo it but are not sure that the file has
> extually been created or not.
Sorry, this isn't true. So I don't know why the errors are suppressed
there..

Anyway, I've committed the object deletion code; it works fine on a
SetCOS 4.4.1, for other cards to be implemented.


Additionally, here is a patch in case you need to provide the user PIN for
deleting the object(s) and you want to specify it on the command line.

It may seem strange to call a keycache function in pkcs15-init tool whereas
it's normally done in the pkcs15init lib. However, in those cases, the PIN
is part of the arguments to create/store/generate an object while here it's
just to link a PIN ref with its value, so IMHO we shouldn't provide this
info as a parameter in sc_pkcs15init_delete_object().

Cheers,
Stef



Index: pkcs15-init.c
===================================================================
--- pkcs15-init.c (revision 2508)
+++ pkcs15-init.c (working copy)
@@ -101,6 +101,7 @@
 static void parse_commandline(int argc, char **argv);
 static void read_options_file(const char *);
 static void ossl_print_errors(void);
+static void set_userpin_ref();
 
 
 enum {
@@ -1069,11 +1070,31 @@
  return r < 0 ? r : count;
 }
 
+/* If the user PIN and it's ID is given, put the pin ref in the keycache */
+static void set_userpin_ref()
+{
+ if ((opt_pins[0] != NULL) && (opt_authid != 0)) {
+ sc_path_t path;
+ sc_pkcs15_id_t auth_id;
+ sc_pkcs15_object_t *pinobj;
+ sc_pkcs15_pin_info_t *pin_info;
+ sc_format_path("3F00", &path);
+ sc_pkcs15_format_id(opt_authid, &auth_id);
+ r = sc_pkcs15_find_pin_by_auth_id(p15card, &auth_id, &pinobj);
+ if (r < 0)
+ fatal("Searching for user PIN %d failed: %s\n", opt_authid, sc_strerror(r));
+ pin_info = (sc_pkcs15_pin_info_t *) pinobj->data;
+ sc_keycache_set_pin_name(&path, pin_info->reference, SC_PKCS15INIT_USER_PIN);
+ }
+}
+
 static int
 do_delete_objects(struct sc_profile *profile, unsigned int opt_delete_flags)
 {
  int r, count = 0;
 
+ set_userpin_ref();
+
  if (opt_delete_flags & SC_PKCS15INIT_DEL_DATA) {
  struct sc_object_id app_oid;
  sc_pkcs15_object_t *obj;

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Tarasov Viktor
In reply to this post by Stef Hoeben
Stef Hoeben wrote:

> Hi,
>
> here a 2nd proposal for deleting pkcs15 objects: now with
> a delete_object() sc_pkcs15init_operation.
> (And most functionality put in pkcs15-init.c iso pkcs15-lib.c)
>
> So each pkcs15init card driver who wants to add support
> for deleting objects has to implement this function.
>
Hi,

do you think that some card-specific pkcs15init operation should be also
implemented
for the object creation,
similar to the one you have done for the object deleting?

In the old API there was new_file() pkcs15init operation,
but not now, in the new API.

Kind wishes,
Viktor.


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Stef Hoeben
Hi Victor,

Tarasov Viktor wrote:

>Stef Hoeben wrote:
>
>  
>
>>Hi,
>>
>>here a 2nd proposal for deleting pkcs15 objects: now with
>>a delete_object() sc_pkcs15init_operation.
>>(And most functionality put in pkcs15-init.c iso pkcs15-lib.c)
>>
>>So each pkcs15init card driver who wants to add support
>>for deleting objects has to implement this function.
>>
>>    
>>
>Hi,
>
>do you think that some card-specific pkcs15init operation should be also
>implemented
>for the object creation,
>similar to the one you have done for the object deleting?
>
>In the old API there was new_file() pkcs15init operation,
>but not now, in the new API.
>
>Kind wishes,
>Viktor.
>
Dunno... Right now, you can choose between the 'old' and 'new' way. The
new way
is preferred (I thought because it allows more sharing of common code,
but getting a
clear overview of it requires days of carefully study and meditation)
and is a bit less
powerfull, IMHO.

So my 2 cents: use the new way if you can, the old way if you must;
untill someone sees the light and clearifies it all (and updates all
card drivers:-)
(This is no critique: it's hard to make something nice that fits all
card -- that is:
all _current_ cards, because the next one you add may require yet
something else..)

Cheers,
Stef

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Support for deleting pkcs15 objects

Tarasov Viktor
Stef Hoeben wrote:

> Hi Victor,
>
> Tarasov Viktor wrote:
>
>> Stef Hoeben wrote:
>>
>>  
>>
>>> Hi,
>>>
>>> here a 2nd proposal for deleting pkcs15 objects: now with
>>> a delete_object() sc_pkcs15init_operation.
>>> (And most functionality put in pkcs15-init.c iso pkcs15-lib.c)
>>>
>>> So each pkcs15init card driver who wants to add support
>>> for deleting objects has to implement this function.
>>>
>>>  
>>
>> Hi,
>>
>> do you think that some card-specific pkcs15init operation should be also
>> implemented
>> for the object creation,
>> similar to the one you have done for the object deleting?
>>
>> In the old API there was new_file() pkcs15init operation,
>> but not now, in the new API.
>>
>> Kind wishes,
>> Viktor.
>>
> Dunno... Right now, you can choose between the 'old' and 'new' way.
> The new way
> is preferred (I thought because it allows more sharing of common code,
> but getting a
> clear overview of it requires days of carefully study and meditation)
> and is a bit less
> powerfull, IMHO.

Untill now I have used the old style API,
but after the following Nils Larsch's mail,
I started the migration of the Oberthur card support to the new API.

Nils Larsch wrote:
<skipped>

> Hmm, your patch changes the "old" style api. I don't really like
> having two different APIs for the same thing (and actually I want
> to remove the old style API in some future release). So what changes
> in the new style api are necessary so it can be used in
> pkcs15-oberthur.c ?
>
> Cheers,
> Nils

end of <Nils Larsch wrote>


Just one suggestion (my 5 kopecks), IMHO, pkcs15init common part should
not impose non-pkcs15 aspects.
Some default behavior and then it's to the card-specific part to decide.

> So my 2 cents: use the new way if you can, the old way if you must;
> untill someone sees the light and clearifies it all (and updates all
> card drivers:-)
> (This is no critique: it's hard to make something nice that fits all
> card -- that is:
> all _current_ cards, because the next one you add may require yet
> something else..)

I'm quite conscious of that.
That's why I try to propose the modifications that change almost nothing
(IMHO) to the existing card drivers.
(One of them is to replace sc_card_t argument in card-specific
pkcs15init operations with the sc_pkcs15_card_t one.
Second is the create_key() prototype, that, seems, you were agree with.)
The general idea is the same: more flexibility with the non-pkcs15
aspects of the pkcs15init.

Sorry, if I am asking too much, and for Oberthur-centric point of view.
Now we have to start the new projects, with the years of support behind.
And I would like to get know where OpenSC will go in the nearest future,
and where can I fork to create our "working horse" OpenSC version.

Once more, sorry for the annoying questions,
I'll stop here,
kind wishes,
Viktor.

> Cheers,
> Stef

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel
12