]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Allow flags when importing objects from PKCS11 URLs. The only flag supported
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 28 Jun 2010 16:07:01 +0000 (18:07 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 28 Jun 2010 16:23:24 +0000 (18:23 +0200)
now is the PKCS11_OBJ_FLAG_LOGIN, which forces login before accessing object on
a token. The reason is that some tokens do not allow access of any data without login.

14 files changed:
doc/examples/ex-cert-select-pkcs11.c
lib/gnutls_pubkey.c
lib/gnutls_x509.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/pkcs11.h
lib/pkcs11.c
lib/pkcs11_write.c
src/certtool-common.h
src/certtool-gaa.c
src/certtool-gaa.h
src/certtool.c
src/certtool.gaa
src/cli.c
src/pkcs11.c

index 741afd3ed04a66d6ea1122e43e1ecedb98149367..8ff4d2ec3b6e7587fa6505d779bbb16ce4f739cf 100644 (file)
@@ -50,7 +50,13 @@ load_keys (void)
 
   gnutls_x509_crt_init (&crt);
 
-  ret = gnutls_x509_crt_import_pkcs11_url (crt, CERT_URL);
+  ret = gnutls_x509_crt_import_pkcs11_url (crt, CERT_URL, 0);
+
+  /* some tokens require login to read data */
+  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    ret = gnutls_x509_crt_import_pkcs11_url (crt, CERT_URL, 
+    GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+
   if (ret < 0)
     {
       fprintf (stderr, "*** Error loading key file: %s\n",
index 58f93b17a289dddc57a1f253a94e1a1caa938643..46d846963a3666dd6d7396a8a213f09a95119fb6 100644 (file)
@@ -735,7 +735,21 @@ int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
        return 0;
 }
 
-int gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url)
+/**
+ * gnutls_pubkey_import_pkcs11_url:
+ * @key: A key of type #gnutls_pubkey_t
+ * @url: A PKCS 11 url
+ * @flags: One of GNUTLS_PKCS11_OBJ_* flags
+ *
+ * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
+ * structure.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
+ *   negative error value.
+ **/
+
+int gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
+       unsigned int flags)
 {
        gnutls_pkcs11_obj_t pcrt;
        int ret;
@@ -746,7 +760,7 @@ int gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url)
                return ret;
        }
 
-       ret = gnutls_pkcs11_obj_import_url(pcrt, url);
+       ret = gnutls_pkcs11_obj_import_url(pcrt, url, flags);
        if (ret < 0) {
                gnutls_assert();
                goto cleanup;
index 5d44359b89bfa3895218333707a66d8f66ca5f86..996c487eddc58c31a348450fae5d7925966fda80 100644 (file)
@@ -569,7 +569,8 @@ gnutls_x509_crt_t * xcrt_list = NULL;
 gnutls_pkcs11_obj_t *pcrt_list=NULL;
 unsigned int pcrt_list_size = 0;
 
-       ret = gnutls_pkcs11_obj_list_import_url( NULL, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED);
+        /* FIXME: should we use login? */
+       ret = gnutls_pkcs11_obj_list_import_url( NULL, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
        if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
                gnutls_assert();
                return ret;
@@ -586,7 +587,7 @@ unsigned int pcrt_list_size = 0;
                return GNUTLS_E_MEMORY_ERROR;
        }
        
-       ret = gnutls_pkcs11_obj_list_import_url( pcrt_list, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED);
+       ret = gnutls_pkcs11_obj_list_import_url( pcrt_list, &pcrt_list_size, url, GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED, 0);
        if (ret < 0) {
                gnutls_assert();
                goto cleanup;
@@ -645,7 +646,10 @@ gnutls_cert * ccert;
       return ret;
     }
   
-  ret = gnutls_x509_crt_import_pkcs11_url(crt, url);
+  ret = gnutls_x509_crt_import_pkcs11_url(crt, url, 0);
+  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+    ret = gnutls_x509_crt_import_pkcs11_url(crt, url, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+
   if (ret < 0)
     {
       gnutls_assert();
index 77e7994a5e87c4d1d2e95b0d8dfac4c8e9d223b5..6eed91dfce73a9c65196134d6df166e63bd8f07f 100644 (file)
@@ -48,7 +48,8 @@ int gnutls_pubkey_import (gnutls_pubkey_t key,
                              gnutls_x509_crt_fmt_t format);
 
 
-int gnutls_pubkey_import_pkcs11_url( gnutls_pubkey_t key, const char* url);
+int gnutls_pubkey_import_pkcs11_url( gnutls_pubkey_t key, const char* url, 
+       unsigned int flags/* GNUTLS_PKCS11_OBJ_FLAG_* */);
 int gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key,
                                    const gnutls_datum_t * p,
                                    const gnutls_datum_t * q,
index 80e4b42a11c6682f6ff87fc1262c4cf405e7f607..e7ae57a5b76ff547407a5f62ec4ea240e5649215 100644 (file)
@@ -48,19 +48,24 @@ void gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t callback, void
 int gnutls_pkcs11_add_provider (const char * name, const char * params);
 int gnutls_pkcs11_obj_init ( gnutls_pkcs11_obj_t *certificate);
 
-int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t, const char * url);
+#define GNUTLS_PKCS11_OBJ_FLAG_LOGIN 1 /* force login in the token for the operation */
+
+int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t, const char * url,
+       unsigned int flags/* GNUTLS_PKCS11_OBJ_FLAG_* */);
 int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t, char** url);
 void gnutls_pkcs11_obj_deinit ( gnutls_pkcs11_obj_t);
 
 int gnutls_pkcs11_obj_export(gnutls_pkcs11_obj_t obj,
                     void *output_data, size_t * output_data_size);
 
-#define GNUTLS_PKCS11_OBJ_FLAG_TRUSTED 1 /* object marked as trusted */
+
+#define GNUTLS_PKCS11_COPY_FLAG_MARK_TRUSTED 1 /* object marked as trusted */
 
 int gnutls_pkcs11_copy_x509_crt(const char* token_url, gnutls_x509_crt_t crt, 
-       const char* label, unsigned int flags /* GNUTLS_PKCS11_OBJ_FLAG_* */);
+       const char* label, unsigned int flags /* GNUTLS_PKCS11_COPY_FLAG_* */);
 int gnutls_pkcs11_copy_x509_privkey(const char* token_url, 
-       gnutls_x509_privkey_t crt, const char* label, unsigned int key_usage /*GNUTLS_KEY_* */);
+       gnutls_x509_privkey_t crt, const char* label, unsigned int key_usage /*GNUTLS_KEY_* */,
+       unsigned int flags /* GNUTLS_PKCS11_COPY_FLAG_* */);
 int gnutls_pkcs11_delete_url(const char* object_url);
 
 typedef enum {
@@ -107,10 +112,14 @@ int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t, vo
 #define GNUTLS_PKCS11_TOKEN_HW 1
 int gnutls_pkcs11_token_get_flags(const char* url, unsigned int *flags);
 
-int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, unsigned int *const n_list, const char* url, gnutls_pkcs11_obj_attr_t flags);
+int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, 
+       unsigned int *const n_list, const char* url, 
+       gnutls_pkcs11_obj_attr_t attrs, 
+       unsigned int flags/* GNUTLS_PKCS11_OBJ_FLAG_* */);
 
 int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pkcs11_crt);
-int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url);
+int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url, 
+       unsigned int flags/* GNUTLS_PKCS11_OBJ_FLAG_* */);
 
 gnutls_pkcs11_obj_type_t gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t certificate);
 const char* gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t);
@@ -118,7 +127,7 @@ const char* gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t);
 int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
                                    unsigned int cert_max,
                                    gnutls_pkcs11_obj_t * const pkcs11_certs,
-                                   unsigned int flags);
+                                   unsigned int flags/* must be zero */);
 
 
 /* private key functions...*/
index ebe4846d1b37a49e89c4f747a739335106087923..ed70073df8437745c25bfa2878d9deb560c5e6b2 100644 (file)
 #define MAX_CERT_SIZE 8*1024
 
 struct gnutls_pkcs11_provider_s {
-    pakchois_module_t *module;
-    unsigned long nslots;
-    ck_slot_id_t *slots;
+       pakchois_module_t *module;
+       unsigned long nslots;
+       ck_slot_id_t *slots;
 };
 
 struct flags_find_data_st {
-    struct pkcs11_url_info info;
-    unsigned int slot_flags;
+       struct pkcs11_url_info info;
+       unsigned int slot_flags;
 };
 
 struct url_find_data_st {
-    gnutls_pkcs11_obj_t crt;
+       gnutls_pkcs11_obj_t crt;
 };
 
 struct crt_find_data_st {
-    gnutls_pkcs11_obj_t *p_list;
-    unsigned int* n_list;
-    unsigned int current;
-    gnutls_pkcs11_obj_attr_t flags;
-    struct pkcs11_url_info info;
+       gnutls_pkcs11_obj_t *p_list;
+       unsigned int *n_list;
+       unsigned int current;
+       gnutls_pkcs11_obj_attr_t flags;
+       struct pkcs11_url_info info;
 };
 
 
@@ -64,102 +64,103 @@ static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS];
 static int active_providers = 0;
 
 static gnutls_pkcs11_pin_callback_t pin_func;
-static voidpin_data;
+static void *pin_data;
 
 gnutls_pkcs11_token_callback_t token_func;
-voidtoken_data;
+void *token_data;
 
 int pkcs11_rv_to_err(ck_rv_t rv)
 {
-    switch(rv) {
-        case CKR_OK:
-            return 0;
-        case CKR_HOST_MEMORY:
-            return GNUTLS_E_MEMORY_ERROR;
-        case CKR_SLOT_ID_INVALID:
-            return GNUTLS_E_PKCS11_SLOT_ERROR;
-        case CKR_ARGUMENTS_BAD:
-        case CKR_MECHANISM_PARAM_INVALID:
-            return GNUTLS_E_INVALID_REQUEST;
-        case CKR_NEED_TO_CREATE_THREADS:
-        case CKR_CANT_LOCK:
-        case CKR_FUNCTION_NOT_PARALLEL:
-        case CKR_MUTEX_BAD:
-        case CKR_MUTEX_NOT_LOCKED:
-            return GNUTLS_E_LOCKING_ERROR;
-        case CKR_ATTRIBUTE_READ_ONLY:
-        case CKR_ATTRIBUTE_SENSITIVE:
-        case CKR_ATTRIBUTE_TYPE_INVALID:
-        case CKR_ATTRIBUTE_VALUE_INVALID:
-            return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
-        case CKR_DEVICE_ERROR:
-        case CKR_DEVICE_MEMORY:
-        case CKR_DEVICE_REMOVED:
-            return GNUTLS_E_PKCS11_DEVICE_ERROR;
-        case CKR_DATA_INVALID:
-        case CKR_DATA_LEN_RANGE:
-        case CKR_ENCRYPTED_DATA_INVALID:
-        case CKR_ENCRYPTED_DATA_LEN_RANGE:
-        case CKR_OBJECT_HANDLE_INVALID:
-            return GNUTLS_E_PKCS11_DATA_ERROR;
-        case CKR_FUNCTION_NOT_SUPPORTED:
-        case CKR_MECHANISM_INVALID:
-            return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
-        case CKR_KEY_HANDLE_INVALID:
-        case CKR_KEY_SIZE_RANGE:
-        case CKR_KEY_TYPE_INCONSISTENT:
-        case CKR_KEY_NOT_NEEDED:
-        case CKR_KEY_CHANGED:
-        case CKR_KEY_NEEDED:
-        case CKR_KEY_INDIGESTIBLE:
-        case CKR_KEY_FUNCTION_NOT_PERMITTED:
-        case CKR_KEY_NOT_WRAPPABLE:
-        case CKR_KEY_UNEXTRACTABLE:
-            return GNUTLS_E_PKCS11_KEY_ERROR;
-        case CKR_PIN_INCORRECT:
-        case CKR_PIN_INVALID:
-        case CKR_PIN_LEN_RANGE:
-            return GNUTLS_E_PKCS11_PIN_ERROR;
-        case CKR_PIN_EXPIRED:
-            return GNUTLS_E_PKCS11_PIN_EXPIRED;
-        case CKR_PIN_LOCKED:
-            return GNUTLS_E_PKCS11_PIN_LOCKED;
-        case CKR_SESSION_CLOSED:
-        case CKR_SESSION_COUNT:
-        case CKR_SESSION_HANDLE_INVALID:
-        case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
-        case CKR_SESSION_READ_ONLY:
-        case CKR_SESSION_EXISTS:
-        case CKR_SESSION_READ_ONLY_EXISTS:
-        case CKR_SESSION_READ_WRITE_SO_EXISTS:
-            return GNUTLS_E_PKCS11_SESSION_ERROR;
-        case CKR_SIGNATURE_INVALID:
-        case CKR_SIGNATURE_LEN_RANGE:
-            return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
-        case CKR_TOKEN_NOT_PRESENT:
-        case CKR_TOKEN_NOT_RECOGNIZED:
-        case CKR_TOKEN_WRITE_PROTECTED:
-            return GNUTLS_E_PKCS11_TOKEN_ERROR;
-        case CKR_USER_ALREADY_LOGGED_IN:
-        case CKR_USER_NOT_LOGGED_IN:
-        case CKR_USER_PIN_NOT_INITIALIZED:
-        case CKR_USER_TYPE_INVALID:
-        case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
-        case CKR_USER_TOO_MANY_TYPES:
-            return GNUTLS_E_PKCS11_USER_ERROR;
-        case CKR_BUFFER_TOO_SMALL:
-            return GNUTLS_E_SHORT_MEMORY_BUFFER;
-        default:
-            return GNUTLS_E_PKCS11_ERROR;
-    }
+       switch (rv) {
+       case CKR_OK:
+               return 0;
+       case CKR_HOST_MEMORY:
+               return GNUTLS_E_MEMORY_ERROR;
+       case CKR_SLOT_ID_INVALID:
+               return GNUTLS_E_PKCS11_SLOT_ERROR;
+       case CKR_ARGUMENTS_BAD:
+       case CKR_MECHANISM_PARAM_INVALID:
+               return GNUTLS_E_INVALID_REQUEST;
+       case CKR_NEED_TO_CREATE_THREADS:
+       case CKR_CANT_LOCK:
+       case CKR_FUNCTION_NOT_PARALLEL:
+       case CKR_MUTEX_BAD:
+       case CKR_MUTEX_NOT_LOCKED:
+               return GNUTLS_E_LOCKING_ERROR;
+       case CKR_ATTRIBUTE_READ_ONLY:
+       case CKR_ATTRIBUTE_SENSITIVE:
+       case CKR_ATTRIBUTE_TYPE_INVALID:
+       case CKR_ATTRIBUTE_VALUE_INVALID:
+               return GNUTLS_E_PKCS11_ATTRIBUTE_ERROR;
+       case CKR_DEVICE_ERROR:
+       case CKR_DEVICE_MEMORY:
+       case CKR_DEVICE_REMOVED:
+               return GNUTLS_E_PKCS11_DEVICE_ERROR;
+       case CKR_DATA_INVALID:
+       case CKR_DATA_LEN_RANGE:
+       case CKR_ENCRYPTED_DATA_INVALID:
+       case CKR_ENCRYPTED_DATA_LEN_RANGE:
+       case CKR_OBJECT_HANDLE_INVALID:
+               return GNUTLS_E_PKCS11_DATA_ERROR;
+       case CKR_FUNCTION_NOT_SUPPORTED:
+       case CKR_MECHANISM_INVALID:
+               return GNUTLS_E_PKCS11_UNSUPPORTED_FEATURE_ERROR;
+       case CKR_KEY_HANDLE_INVALID:
+       case CKR_KEY_SIZE_RANGE:
+       case CKR_KEY_TYPE_INCONSISTENT:
+       case CKR_KEY_NOT_NEEDED:
+       case CKR_KEY_CHANGED:
+       case CKR_KEY_NEEDED:
+       case CKR_KEY_INDIGESTIBLE:
+       case CKR_KEY_FUNCTION_NOT_PERMITTED:
+       case CKR_KEY_NOT_WRAPPABLE:
+       case CKR_KEY_UNEXTRACTABLE:
+               return GNUTLS_E_PKCS11_KEY_ERROR;
+       case CKR_PIN_INCORRECT:
+       case CKR_PIN_INVALID:
+       case CKR_PIN_LEN_RANGE:
+               return GNUTLS_E_PKCS11_PIN_ERROR;
+       case CKR_PIN_EXPIRED:
+               return GNUTLS_E_PKCS11_PIN_EXPIRED;
+       case CKR_PIN_LOCKED:
+               return GNUTLS_E_PKCS11_PIN_LOCKED;
+       case CKR_SESSION_CLOSED:
+       case CKR_SESSION_COUNT:
+       case CKR_SESSION_HANDLE_INVALID:
+       case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
+       case CKR_SESSION_READ_ONLY:
+       case CKR_SESSION_EXISTS:
+       case CKR_SESSION_READ_ONLY_EXISTS:
+       case CKR_SESSION_READ_WRITE_SO_EXISTS:
+               return GNUTLS_E_PKCS11_SESSION_ERROR;
+       case CKR_SIGNATURE_INVALID:
+       case CKR_SIGNATURE_LEN_RANGE:
+               return GNUTLS_E_PKCS11_SIGNATURE_ERROR;
+       case CKR_TOKEN_NOT_PRESENT:
+       case CKR_TOKEN_NOT_RECOGNIZED:
+       case CKR_TOKEN_WRITE_PROTECTED:
+               return GNUTLS_E_PKCS11_TOKEN_ERROR;
+       case CKR_USER_ALREADY_LOGGED_IN:
+       case CKR_USER_NOT_LOGGED_IN:
+       case CKR_USER_PIN_NOT_INITIALIZED:
+       case CKR_USER_TYPE_INVALID:
+       case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
+       case CKR_USER_TOO_MANY_TYPES:
+               return GNUTLS_E_PKCS11_USER_ERROR;
+       case CKR_BUFFER_TOO_SMALL:
+               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+       default:
+               return GNUTLS_E_PKCS11_ERROR;
+       }
 }
 
 /* Fake scan */
 void pkcs11_rescan_slots(void)
 {
-unsigned long slots;
+       unsigned long slots;
 
-    pakchois_get_slot_list(providers[active_providers-1].module, 0, NULL, &slots);
+       pakchois_get_slot_list(providers[active_providers - 1].module, 0,
+                              NULL, &slots);
 }
 
 /**
@@ -174,48 +175,58 @@ unsigned long slots;
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_add_provider (const char * name, const char * params)
+int gnutls_pkcs11_add_provider(const char *name, const char *params)
 {
 
-    if (active_providers >= MAX_PROVIDERS) {
-        gnutls_assert();
-        return GNUTLS_E_CONSTRAINT_ERROR;
-    }
-
-    active_providers++;
-    if (pakchois_module_load_abs(&providers[active_providers-1].module, name) != CKR_OK) {
-        gnutls_assert();
-        _gnutls_debug_log("p11: Cannot load provider %s\n", name);
-        active_providers--;
-        return GNUTLS_E_PKCS11_LOAD_ERROR;
-    }
-
-    /* cache the number of slots in this module */
-    if (pakchois_get_slot_list(providers[active_providers-1].module, 0, NULL, &providers[active_providers-1].nslots) != CKR_OK) {
-        gnutls_assert();
-        goto fail;
-    }
-    
-    providers[active_providers-1].slots = gnutls_malloc(sizeof(*providers[active_providers-1].slots)*providers[active_providers-1].nslots);
-    if (providers[active_providers-1].slots==NULL) {
-        gnutls_assert();
-        goto fail;
-    }
-
-    if (pakchois_get_slot_list(providers[active_providers-1].module, 0, providers[active_providers-1].slots, &providers[active_providers-1].nslots) != CKR_OK)  {
-        gnutls_assert();
-        gnutls_free(providers[active_providers-1].slots);
-        goto fail;
-    }
-    
-    _gnutls_debug_log("p11: loaded provider '%s' with %d slots\n", name, (int)providers[active_providers-1].nslots);
-
-    return 0;
-
-fail:
-    pakchois_module_destroy(providers[active_providers-1].module);
-    active_providers--;
-    return GNUTLS_E_PKCS11_LOAD_ERROR;
+       if (active_providers >= MAX_PROVIDERS) {
+               gnutls_assert();
+               return GNUTLS_E_CONSTRAINT_ERROR;
+       }
+
+       active_providers++;
+       if (pakchois_module_load_abs
+           (&providers[active_providers - 1].module, name) != CKR_OK) {
+               gnutls_assert();
+               _gnutls_debug_log("p11: Cannot load provider %s\n", name);
+               active_providers--;
+               return GNUTLS_E_PKCS11_LOAD_ERROR;
+       }
+
+       /* cache the number of slots in this module */
+       if (pakchois_get_slot_list
+           (providers[active_providers - 1].module, 0, NULL,
+            &providers[active_providers - 1].nslots) != CKR_OK) {
+               gnutls_assert();
+               goto fail;
+       }
+
+       providers[active_providers - 1].slots =
+           gnutls_malloc(sizeof(*providers[active_providers - 1].slots) *
+                         providers[active_providers - 1].nslots);
+       if (providers[active_providers - 1].slots == NULL) {
+               gnutls_assert();
+               goto fail;
+       }
+
+       if (pakchois_get_slot_list
+           (providers[active_providers - 1].module, 0,
+            providers[active_providers - 1].slots,
+            &providers[active_providers - 1].nslots) != CKR_OK) {
+               gnutls_assert();
+               gnutls_free(providers[active_providers - 1].slots);
+               goto fail;
+       }
+
+       _gnutls_debug_log("p11: loaded provider '%s' with %d slots\n",
+                         name,
+                         (int) providers[active_providers - 1].nslots);
+
+       return 0;
+
+      fail:
+       pakchois_module_destroy(providers[active_providers - 1].module);
+       active_providers--;
+       return GNUTLS_E_PKCS11_LOAD_ERROR;
 
 }
 
@@ -234,63 +245,67 @@ fail:
  *
  * Returns: zero on success or a negative value on error.
  **/
-int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t crt, gnutls_pkcs11_obj_info_t itype, 
-    void* output, size_t* output_size)
+int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t crt,
+                              gnutls_pkcs11_obj_info_t itype,
+                              void *output, size_t * output_size)
 {
-    return pkcs11_get_info(&crt->info, itype, output, output_size);
+       return pkcs11_get_info(&crt->info, itype, output, output_size);
 }
 
-int pkcs11_get_info(struct pkcs11_url_info *info, gnutls_pkcs11_obj_info_t itype,
-    void* output, size_t* output_size)
+int pkcs11_get_info(struct pkcs11_url_info *info,
+                   gnutls_pkcs11_obj_info_t itype, void *output,
+                   size_t * output_size)
 {
-    const char* str = NULL;
-    size_t len;
-
-    switch(itype) {
-        case GNUTLS_PKCS11_OBJ_ID:
-            if (*output_size < info->certid_raw_size) {
-                *output_size = info->certid_raw_size;
-                return GNUTLS_E_SHORT_MEMORY_BUFFER;
-            }
-            if (output) memcpy(output, info->certid_raw, info->certid_raw_size);
-            *output_size = info->certid_raw_size;
-            
-            return 0;
-        case GNUTLS_PKCS11_OBJ_ID_HEX:
-            str = info->id;
-            break;
-        case GNUTLS_PKCS11_OBJ_LABEL:
-            str = info->label;
-            break;
-        case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
-            str = info->token;
-            break;
-        case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
-            str = info->serial;
-            break;
-        case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
-            str = info->manufacturer;
-            break;
-        case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
-            str = info->model;
-            break;
-        default:
-            gnutls_assert();
-            return GNUTLS_E_INVALID_REQUEST;
-    }
-
-    len = strlen(str);
-
-    if (len+1>*output_size) {
-        *output_size = len+1;
-        return GNUTLS_E_SHORT_MEMORY_BUFFER;
-    }
-
-    strcpy(output, str);
-
-    *output_size = len;
-
-    return 0;
+       const char *str = NULL;
+       size_t len;
+
+       switch (itype) {
+       case GNUTLS_PKCS11_OBJ_ID:
+               if (*output_size < info->certid_raw_size) {
+                       *output_size = info->certid_raw_size;
+                       return GNUTLS_E_SHORT_MEMORY_BUFFER;
+               }
+               if (output)
+                       memcpy(output, info->certid_raw,
+                              info->certid_raw_size);
+               *output_size = info->certid_raw_size;
+
+               return 0;
+       case GNUTLS_PKCS11_OBJ_ID_HEX:
+               str = info->id;
+               break;
+       case GNUTLS_PKCS11_OBJ_LABEL:
+               str = info->label;
+               break;
+       case GNUTLS_PKCS11_OBJ_TOKEN_LABEL:
+               str = info->token;
+               break;
+       case GNUTLS_PKCS11_OBJ_TOKEN_SERIAL:
+               str = info->serial;
+               break;
+       case GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER:
+               str = info->manufacturer;
+               break;
+       case GNUTLS_PKCS11_OBJ_TOKEN_MODEL:
+               str = info->model;
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       len = strlen(str);
+
+       if (len + 1 > *output_size) {
+               *output_size = len + 1;
+               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+       }
+
+       strcpy(output, str);
+
+       *output_size = len;
+
+       return 0;
 }
 
 static int init = 0;
@@ -312,57 +327,62 @@ static int init = 0;
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_init(unsigned int flags, const charconfigfile)
+int gnutls_pkcs11_init(unsigned int flags, const char *configfile)
 {
-    int ret;
-    
-    if (init != 0) {
-        init++;
-        return 0;
-    }
-    init++;
-
-    if (flags == GNUTLS_PKCS11_FLAG_MANUAL)
-        return 0;
-    else {
-        FILE *fp;
-        char line[512];
-        const char* library;
-        
-        if (configfile == NULL)
-            configfile = "/etc/gnutls/pkcs11.conf";
-        
-        fp = fopen(configfile, "r");
-        if (fp == NULL) {
-            gnutls_assert();
-            _gnutls_debug_log("Cannot load %s\n", configfile);
-            return GNUTLS_E_FILE_ERROR;
-        }
-        
-        while (fgets (line, sizeof (line), fp) != NULL) {
-            if (strncmp(line, "load", sizeof("load")-1) == 0) {
-                char* p;
-                p = strchr(line, '=');
-                if (p==NULL) continue;
-                
-                library = ++p;
-                
-                p = strchr(line, '\n');
-                if (p!=NULL) {
-                    *p=0;
-                }
-
-                ret = gnutls_pkcs11_add_provider(library, NULL);
-                if (ret < 0) {
-                    gnutls_assert();
-                    _gnutls_debug_log("Cannot load provider: %s\n", library);
-                    continue;
-                }
-            }
-        }
-    }
-    
-    return 0;
+       int ret;
+
+       if (init != 0) {
+               init++;
+               return 0;
+       }
+       init++;
+
+       if (flags == GNUTLS_PKCS11_FLAG_MANUAL)
+               return 0;
+       else {
+               FILE *fp;
+               char line[512];
+               const char *library;
+
+               if (configfile == NULL)
+                       configfile = "/etc/gnutls/pkcs11.conf";
+
+               fp = fopen(configfile, "r");
+               if (fp == NULL) {
+                       gnutls_assert();
+                       _gnutls_debug_log("Cannot load %s\n", configfile);
+                       return GNUTLS_E_FILE_ERROR;
+               }
+
+               while (fgets(line, sizeof(line), fp) != NULL) {
+                       if (strncmp(line, "load", sizeof("load") - 1) == 0) {
+                               char *p;
+                               p = strchr(line, '=');
+                               if (p == NULL)
+                                       continue;
+
+                               library = ++p;
+
+                               p = strchr(line, '\n');
+                               if (p != NULL) {
+                                       *p = 0;
+                               }
+
+                               ret =
+                                   gnutls_pkcs11_add_provider(library,
+                                                              NULL);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       _gnutls_debug_log
+                                           ("Cannot load provider: %s\n",
+                                            library);
+                                       continue;
+                               }
+                       }
+               }
+       }
+
+       return 0;
 }
 
 /**
@@ -371,23 +391,22 @@ int gnutls_pkcs11_init(unsigned int flags, const char* configfile)
  * This function will deinitialize the PKCS 11 subsystem in gnutls.
  *
  **/
-void gnutls_pkcs11_deinit (void)
+void gnutls_pkcs11_deinit(void)
 {
-    int i;
-
-    init--;
-    if (init > 0)
-        return;
-    if (init < 0)
-      {
-        init = 0;
-        return;
-      }
-    
-    for (i=0;i<active_providers;i++) {
-        pakchois_module_destroy(providers[i].module);
-    }
-    active_providers = 0;
+       int i;
+
+       init--;
+       if (init > 0)
+               return;
+       if (init < 0) {
+               init = 0;
+               return;
+       }
+
+       for (i = 0; i < active_providers; i++) {
+               pakchois_module_destroy(providers[i].module);
+       }
+       active_providers = 0;
 }
 
 /**
@@ -424,10 +443,10 @@ void gnutls_pkcs11_deinit (void)
  *   negative error value.
  **/
 void gnutls_pkcs11_set_pin_function(gnutls_pkcs11_pin_callback_t fn,
-                                void *userdata)
+                                   void *userdata)
 {
-    pin_func = fn;
-    pin_data = userdata;
+       pin_func = fn;
+       pin_data = userdata;
 }
 
 /**
@@ -442,283 +461,292 @@ void gnutls_pkcs11_set_pin_function(gnutls_pkcs11_pin_callback_t fn,
  *   negative error value.
  **/
 void gnutls_pkcs11_set_token_function(gnutls_pkcs11_token_callback_t fn,
-                                void *userdata)
+                                     void *userdata)
 {
-    token_func = fn;
-    token_data = userdata;
+       token_func = fn;
+       token_data = userdata;
 }
 
-static int unescape_string (char* output, const char* input, size_t* size, char terminator)
+static int unescape_string(char *output, const char *input, size_t * size,
+                          char terminator)
 {
-    gnutls_buffer_st str;
-    int ret = 0;
-    char* p;
-    int len;
-    
-    _gnutls_buffer_init(&str);
-    
-    /* find terminator */
-    p = strchr(input, terminator);
-    if (p!=NULL)
-        len = p-input;
-    else
-        len = strlen(input);
-
-    ret = _gnutls_buffer_append_data(&str, input, len);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = _gnutls_buffer_unescape(&str);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = _gnutls_buffer_append_data(&str, "", 1);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    _gnutls_buffer_pop_data(&str, output, size);
-
-    _gnutls_buffer_clear(&str);
-
-    return ret;
-}
+       gnutls_buffer_st str;
+       int ret = 0;
+       char *p;
+       int len;
+
+       _gnutls_buffer_init(&str);
+
+       /* find terminator */
+       p = strchr(input, terminator);
+       if (p != NULL)
+               len = p - input;
+       else
+               len = strlen(input);
+
+       ret = _gnutls_buffer_append_data(&str, input, len);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-int pkcs11_url_to_info(const char* url, struct pkcs11_url_info* info)
-{
-int ret;
-char* p1, *p2;
-size_t l;
+       ret = _gnutls_buffer_unescape(&str);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-    memset( info, 0, sizeof(*info));
+       ret = _gnutls_buffer_append_data(&str, "", 1);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-    if (strstr(url, "pkcs11:")==NULL) {
-        ret = GNUTLS_E_PARSING_ERROR;
-        goto cleanup;
-    }
+       _gnutls_buffer_pop_data(&str, output, size);
 
-    if ((p1=strstr(url, "manufacturer="))!= NULL) {
-        p1+=sizeof("manufacturer=")-1;
-        l=sizeof (info->manufacturer);
+       _gnutls_buffer_clear(&str);
 
-        ret = unescape_string(info->manufacturer, p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       return ret;
+}
 
-    if ((p1=strstr(url, "token="))!= NULL) {
-        p1+=sizeof("token=")-1;
-        l=sizeof (info->token);
+int pkcs11_url_to_info(const char *url, struct pkcs11_url_info *info)
+{
+       int ret;
+       char *p1, *p2;
+       size_t l;
 
-        ret = unescape_string(info->token, p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       memset(info, 0, sizeof(*info));
 
-    if ((p1=strstr(url, "object="))!= NULL) {
-        p1+=sizeof("object=")-1;
-        l=sizeof (info->label);
+       if (strstr(url, "pkcs11:") == NULL) {
+               ret = GNUTLS_E_PARSING_ERROR;
+               goto cleanup;
+       }
 
-        ret = unescape_string(info->label, p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       if ((p1 = strstr(url, "manufacturer=")) != NULL) {
+               p1 += sizeof("manufacturer=") - 1;
+               l = sizeof(info->manufacturer);
 
-    if ((p1=strstr(url, "serial="))!= NULL) {
-        p1+=sizeof("serial=")-1;
-        l=sizeof (info->serial);
+               ret = unescape_string(info->manufacturer, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-        ret = unescape_string (info->serial, p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       if ((p1 = strstr(url, "token=")) != NULL) {
+               p1 += sizeof("token=") - 1;
+               l = sizeof(info->token);
 
-    if ((p1=strstr(url, "model="))!= NULL) {
-        p1+=sizeof("model=")-1;
-        l=sizeof (info->model);
+               ret = unescape_string(info->token, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-        ret = unescape_string (info->model,
-                        p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       if ((p1 = strstr(url, "object=")) != NULL) {
+               p1 += sizeof("object=") - 1;
+               l = sizeof(info->label);
 
-    if ((p1=strstr(url, "objecttype="))!= NULL) {
-        p1+=sizeof("objecttype=")-1;
-        l=sizeof (info->model);
+               ret = unescape_string(info->label, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-        ret = unescape_string (info->type,
-                        p1, &l, ';');
-        if (ret < 0) {
-                goto cleanup;
-        }
-    }
+       if ((p1 = strstr(url, "serial=")) != NULL) {
+               p1 += sizeof("serial=") - 1;
+               l = sizeof(info->serial);
 
-    if (((p1=strstr(url, ";id="))!= NULL) || ((p1=strstr(url, ":id="))!= NULL)) {
-        p1+=sizeof(";id=")-1;
+               ret = unescape_string(info->serial, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-        if ((p2=strchr(p1, ';'))== NULL) {
-            l = strlen(p1);
-        } else {
-            l = p2 - p1;
-        }
+       if ((p1 = strstr(url, "model=")) != NULL) {
+               p1 += sizeof("model=") - 1;
+               l = sizeof(info->model);
 
-        if (l > sizeof(info->id)-1) {
-            gnutls_assert();
-            ret = GNUTLS_E_PARSING_ERROR;
-        }
+               ret = unescape_string(info->model, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-        memcpy(info->id, p1, l);
-        info->id[l] = 0;
+       if ((p1 = strstr(url, "objecttype=")) != NULL) {
+               p1 += sizeof("objecttype=") - 1;
+               l = sizeof(info->model);
 
-        /* convert to raw */
-        info->certid_raw_size = sizeof(info->certid_raw);
-        ret = _gnutls_hex2bin(info->id, strlen(info->id), info->certid_raw, &info->certid_raw_size);
-        if (ret < 0) {
-            gnutls_assert();
-            goto cleanup;
-        }
-    }
-    
-    ret = 0;
-   
-cleanup:
+               ret = unescape_string(info->type, p1, &l, ';');
+               if (ret < 0) {
+                       goto cleanup;
+               }
+       }
 
-    return ret;
+       if (((p1 = strstr(url, ";id=")) != NULL)
+           || ((p1 = strstr(url, ":id=")) != NULL)) {
+               p1 += sizeof(";id=") - 1;
+
+               if ((p2 = strchr(p1, ';')) == NULL) {
+                       l = strlen(p1);
+               } else {
+                       l = p2 - p1;
+               }
+
+               if (l > sizeof(info->id) - 1) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_PARSING_ERROR;
+               }
+
+               memcpy(info->id, p1, l);
+               info->id[l] = 0;
+
+               /* convert to raw */
+               info->certid_raw_size = sizeof(info->certid_raw);
+               ret =
+                   _gnutls_hex2bin(info->id, strlen(info->id),
+                                   info->certid_raw,
+                                   &info->certid_raw_size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+       }
+
+       ret = 0;
+
+      cleanup:
+
+       return ret;
 
 }
 
 #define INVALID_CHARS       "\\/\"'%&#@!?$* <>{}[]()`|:;,.+-"
 
-static int append(gnutls_buffer_st* dest, const char* tname, const char* p11name, int init)
+static int append(gnutls_buffer_st * dest, const char *tname,
+                 const char *p11name, int init)
 {
-        gnutls_buffer_st tmpstr;
-        int ret;
+       gnutls_buffer_st tmpstr;
+       int ret;
 
-        _gnutls_buffer_init(&tmpstr);
-        if ((ret=_gnutls_buffer_append_str(&tmpstr, tname))<0) {
-                gnutls_assert();
-                goto cleanup;
-        }
+       _gnutls_buffer_init(&tmpstr);
+       if ((ret = _gnutls_buffer_append_str(&tmpstr, tname)) < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
-        ret = _gnutls_buffer_escape(&tmpstr, INVALID_CHARS);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
+       ret = _gnutls_buffer_escape(&tmpstr, INVALID_CHARS);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
-        if ((ret=_gnutls_buffer_append_data(&tmpstr, "", 1)) < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
+       if ((ret = _gnutls_buffer_append_data(&tmpstr, "", 1)) < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
-        if ((ret=_gnutls_buffer_append_printf(dest, "%s%s=%s", (init!=0)?";":"", p11name, tmpstr.data)) < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
+       if ((ret =
+            _gnutls_buffer_append_printf(dest, "%s%s=%s",
+                                         (init != 0) ? ";" : "", p11name,
+                                         tmpstr.data)) < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
 
-        ret = 0;
+       ret = 0;
 
-cleanup:
-        _gnutls_buffer_clear(&tmpstr);
+      cleanup:
+       _gnutls_buffer_clear(&tmpstr);
 
-        return ret;
+       return ret;
 
 }
 
 
-int pkcs11_info_to_url(const struct pkcs11_url_info* info, char** url)
+int pkcs11_info_to_url(const struct pkcs11_url_info *info, char **url)
 {
-    gnutls_buffer_st str;
-    int init = 0;
-    int ret;
-    
-    _gnutls_buffer_init (&str);
-
-    _gnutls_buffer_append_str(&str, "pkcs11:");
-
-    if (info->token[0]) {
-        ret = append(&str, info->token, "token", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
-
-    if (info->serial[0]) {
-        ret = append(&str, info->serial, "serial", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
-
-    if (info->model[0]) {
-        ret = append(&str, info->model, "model", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
+       gnutls_buffer_st str;
+       int init = 0;
+       int ret;
 
+       _gnutls_buffer_init(&str);
 
-    if (info->manufacturer[0]) {
-        ret = append(&str, info->manufacturer, "manufacturer", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
-
-    if (info->label[0]) {
-        ret = append(&str, info->label, "object", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
-
-    if (info->type[0]) {
-        ret = append(&str, info->type, "objecttype", init);
-        if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-        }
-        init = 1;
-    }
-
-    if (info->id[0] != 0) {
-        ret = _gnutls_buffer_append_printf(&str, ";id=%s", info->id);
-        if (ret < 0) {
-            gnutls_assert();
-            return ret;
-        }
-    }
-    
-    _gnutls_buffer_append_data(&str, "", 1);
+       _gnutls_buffer_append_str(&str, "pkcs11:");
+
+       if (info->token[0]) {
+               ret = append(&str, info->token, "token", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+       if (info->serial[0]) {
+               ret = append(&str, info->serial, "serial", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+       if (info->model[0]) {
+               ret = append(&str, info->model, "model", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+
+       if (info->manufacturer[0]) {
+               ret =
+                   append(&str, info->manufacturer, "manufacturer", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+       if (info->label[0]) {
+               ret = append(&str, info->label, "object", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+       if (info->type[0]) {
+               ret = append(&str, info->type, "objecttype", init);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+               init = 1;
+       }
+
+       if (info->id[0] != 0) {
+               ret =
+                   _gnutls_buffer_append_printf(&str, ";id=%s", info->id);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+       }
+
+       _gnutls_buffer_append_data(&str, "", 1);
 
-    *url = str.data;
-    
-    return 0;
+       *url = str.data;
 
-cleanup:
-    _gnutls_buffer_clear(&str);
-    return ret;
+       return 0;
+
+      cleanup:
+       _gnutls_buffer_clear(&str);
+       return ret;
 }
 
 /**
@@ -732,13 +760,13 @@ cleanup:
  **/
 int gnutls_pkcs11_obj_init(gnutls_pkcs11_obj_t * crt)
 {
-    *crt = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_obj_st));
-    if (*crt == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_MEMORY_ERROR;
-    }
-    return 0;
+       *crt = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_obj_st));
+       if (*crt == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       return 0;
 }
 
 /**
@@ -749,8 +777,8 @@ int gnutls_pkcs11_obj_init(gnutls_pkcs11_obj_t * crt)
  **/
 void gnutls_pkcs11_obj_deinit(gnutls_pkcs11_obj_t crt)
 {
-    _gnutls_free_datum(&crt->raw);
-    free(crt);
+       _gnutls_free_datum(&crt->raw);
+       free(crt);
 }
 
 /**
@@ -776,75 +804,78 @@ void gnutls_pkcs11_obj_deinit(gnutls_pkcs11_obj_t crt)
  **/
 int
 gnutls_pkcs11_obj_export(gnutls_pkcs11_obj_t obj,
-                    void *output_data,
-                    size_t * output_data_size)
+                        void *output_data,
+                        size_t * output_data_size)
 {
        if (obj == NULL || obj->raw.data == NULL) {
                gnutls_assert();
                return GNUTLS_E_INVALID_REQUEST;
        }
 
-    if (output_data==NULL || *output_data_size < obj->raw.size) {
-        *output_data_size = obj->raw.size;
-        gnutls_assert();
-        return GNUTLS_E_SHORT_MEMORY_BUFFER;
-    }
-    *output_data_size = obj->raw.size;
+       if (output_data == NULL || *output_data_size < obj->raw.size) {
+               *output_data_size = obj->raw.size;
+               gnutls_assert();
+               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+       }
+       *output_data_size = obj->raw.size;
 
-    memcpy(output_data, obj->raw.data, obj->raw.size);
-    return 0;
+       memcpy(output_data, obj->raw.data, obj->raw.size);
+       return 0;
 }
 
 static void terminate_string(unsigned char *str, size_t len)
 {
-    unsigned char *ptr = str + len - 1;
+       unsigned char *ptr = str + len - 1;
 
-    while ((*ptr == ' ' || *ptr == '\t' || *ptr == '\0') && ptr >= str)
-        ptr--;
+       while ((*ptr == ' ' || *ptr == '\t' || *ptr == '\0') && ptr >= str)
+               ptr--;
 
-    if (ptr == str - 1)
-        str[0] = '\0';
-    else if (ptr == str + len - 1)
-        str[len-1] = '\0';
-    else
-        ptr[1] = '\0';
+       if (ptr == str - 1)
+               str[0] = '\0';
+       else if (ptr == str + len - 1)
+               str[len - 1] = '\0';
+       else
+               ptr[1] = '\0';
 }
 
-int pkcs11_find_object (pakchois_session_t** _pks, ck_object_handle_t* _obj,
-    struct pkcs11_url_info *info, token_creds_st* creds, unsigned int flags)
+int pkcs11_find_object(pakchois_session_t ** _pks,
+                      ck_object_handle_t * _obj,
+                      struct pkcs11_url_info *info,
+                      token_creds_st * creds, unsigned int flags)
 {
-int ret;
-pakchois_session_t *pks;
-ck_object_handle_t obj;
-ck_object_class_t class;
-struct ck_attribute a[4];
-int a_vals = 0;
-unsigned long count;
-ck_rv_t rv;
-
-    class = pkcs11_strtype_to_class(info->type);
-    if (class == -1) {
-        gnutls_assert();
-        return GNUTLS_E_INVALID_REQUEST;
-    }
-
-    ret = pkcs11_open_session (&pks, info, creds, flags);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
+       int ret;
+       pakchois_session_t *pks;
+       ck_object_handle_t obj;
+       ck_object_class_t class;
+       struct ck_attribute a[4];
+       int a_vals = 0;
+       unsigned long count;
+       ck_rv_t rv;
+
+       class = pkcs11_strtype_to_class(info->type);
+       if (class == -1) {
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       ret =
+           pkcs11_open_session(&pks, info, creds, flags & SESSION_LOGIN);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
        a[a_vals].type = CKA_CLASS;
        a[a_vals].value = &class;
        a[a_vals].value_len = sizeof class;
-    a_vals++;
+       a_vals++;
 
-    if (info->certid_raw_size > 0) {
-        a[a_vals].type = CKA_ID;
-        a[a_vals].value = info->certid_raw;
-        a[a_vals].value_len = info->certid_raw_size;
-        a_vals++;
-    }
+       if (info->certid_raw_size > 0) {
+               a[a_vals].type = CKA_ID;
+               a[a_vals].value = info->certid_raw;
+               a[a_vals].value_len = info->certid_raw_size;
+               a_vals++;
+       }
 
        rv = pakchois_find_objects_init(pks, a, a_vals);
        if (rv != CKR_OK) {
@@ -854,540 +885,653 @@ ck_rv_t rv;
                goto fail;
        }
 
-    if (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
-              && count == 1) {
-            *_obj = obj;
-            *_pks = pks;
-            pakchois_find_objects_final(pks);
-            return 0;
+       if (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
+           && count == 1) {
+               *_obj = obj;
+               *_pks = pks;
+               pakchois_find_objects_final(pks);
+               return 0;
 
-    }
+       }
 
-    pakchois_find_objects_final(pks);
-fail:
-    pakchois_close_session(pks);
+       pakchois_find_objects_final(pks);
+      fail:
+       pakchois_close_session(pks);
 
-    return ret;
+       return ret;
 }
 
-int pkcs11_open_session (pakchois_session_t** _pks, struct pkcs11_url_info *info, 
-    token_creds_st* creds, unsigned int flags)
+int pkcs11_open_session(pakchois_session_t ** _pks,
+                       struct pkcs11_url_info *info,
+                       token_creds_st * creds, unsigned int flags)
 {
-    ck_rv_t rv;
-    int x, z, ret;
-    pakchois_session_t *pks = NULL;
-
-    for (x=0;x<active_providers;x++) {
-        for (z=0;z<providers[x].nslots;z++) {
-            struct token_info tinfo;
-
-            rv = pakchois_open_session(providers[x].module, providers[x].slots[z], 
-                ((flags&SESSION_WRITE)?CKF_RW_SESSION:0)|CKF_SERIAL_SESSION, NULL, NULL, &pks);
-            if (rv != CKR_OK) {
-                continue;
-            }
-
-            if (pakchois_get_token_info(providers[x].module, providers[x].slots[z], &tinfo.tinfo) != CKR_OK) {
-                goto next;
-            }
-            tinfo.sid = providers[x].slots[z];
-            tinfo.prov = &providers[x];
-
-            if (pakchois_get_slot_info(providers[x].module, providers[x].slots[z], &tinfo.sinfo) != CKR_OK) {
-                goto next;
-            }
-
-            /* XXX make wrapper for token_info? */
-            terminate_string(tinfo.tinfo.manufacturer_id, sizeof tinfo.tinfo.manufacturer_id);
-            terminate_string(tinfo.tinfo.label, sizeof tinfo.tinfo.label);
-            terminate_string(tinfo.tinfo.model, sizeof tinfo.tinfo.model);
-            terminate_string(tinfo.tinfo.serial_number, sizeof tinfo.tinfo.serial_number);
-
-            if (pkcs11_token_matches_info( info, &tinfo.tinfo) < 0) {
-                goto next;
-            }
-
-            if (flags&SESSION_LOGIN) {
-                ret = pkcs11_login(pks, &tinfo, creds);
-                if (ret < 0) {
-                    gnutls_assert();
-                    pakchois_close_session(pks);
-                    return ret;
-                }
-            }
-
-            /* ok found */
-            *_pks = pks;
-            return 0;
-            
-next:
-            pakchois_close_session(pks);
-        }
-    }
+       ck_rv_t rv;
+       int x, z, ret;
+       pakchois_session_t *pks = NULL;
+
+       for (x = 0; x < active_providers; x++) {
+               for (z = 0; z < providers[x].nslots; z++) {
+                       struct token_info tinfo;
+
+                       rv = pakchois_open_session(providers[x].module,
+                                                  providers[x].slots[z],
+                                                  ((flags & SESSION_WRITE)
+                                                   ? CKF_RW_SESSION : 0) |
+                                                  CKF_SERIAL_SESSION,
+                                                  NULL, NULL, &pks);
+                       if (rv != CKR_OK) {
+                               continue;
+                       }
+
+                       if (pakchois_get_token_info
+                           (providers[x].module, providers[x].slots[z],
+                            &tinfo.tinfo) != CKR_OK) {
+                               goto next;
+                       }
+                       tinfo.sid = providers[x].slots[z];
+                       tinfo.prov = &providers[x];
+
+                       if (pakchois_get_slot_info
+                           (providers[x].module, providers[x].slots[z],
+                            &tinfo.sinfo) != CKR_OK) {
+                               goto next;
+                       }
+
+                       /* XXX make wrapper for token_info? */
+                       terminate_string(tinfo.tinfo.manufacturer_id,
+                                        sizeof tinfo.tinfo.
+                                        manufacturer_id);
+                       terminate_string(tinfo.tinfo.label,
+                                        sizeof tinfo.tinfo.label);
+                       terminate_string(tinfo.tinfo.model,
+                                        sizeof tinfo.tinfo.model);
+                       terminate_string(tinfo.tinfo.serial_number,
+                                        sizeof tinfo.tinfo.serial_number);
+
+                       if (pkcs11_token_matches_info(info, &tinfo.tinfo) <
+                           0) {
+                               goto next;
+                       }
+
+                       if (flags & SESSION_LOGIN) {
+                               ret = pkcs11_login(pks, &tinfo, creds);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       pakchois_close_session(pks);
+                                       return ret;
+                               }
+                       }
+
+                       /* ok found */
+                       *_pks = pks;
+                       return 0;
+
+                     next:
+                       pakchois_close_session(pks);
+               }
+       }
 
-    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
 }
 
 
-int _pkcs11_traverse_tokens (find_func_t find_func, void* input, 
-    unsigned int flags)
+int _pkcs11_traverse_tokens(find_func_t find_func, void *input,
+                           unsigned int flags)
 {
-    ck_rv_t rv;
-    int found = 0, x, z, ret;
-    pakchois_session_t *pks = NULL;
-
-    for (x=0;x<active_providers;x++) {
-        for (z=0;z<providers[x].nslots;z++) {
-            struct token_info info;
-
-            ret = GNUTLS_E_PKCS11_ERROR;
-
-            rv = pakchois_open_session(providers[x].module, providers[x].slots[z], 
-                ((flags&SESSION_WRITE)?CKF_RW_SESSION:0)|CKF_SERIAL_SESSION, NULL, NULL, &pks);
-            if (rv != CKR_OK) {
-                continue;
-            }
-
-            if (pakchois_get_token_info(providers[x].module, providers[x].slots[z], &info.tinfo) != CKR_OK) {
-                goto next;
-            }
-            info.sid = providers[x].slots[z];
-            info.prov = &providers[x];
-
-            if (pakchois_get_slot_info(providers[x].module, providers[x].slots[z], &info.sinfo) != CKR_OK) {
-                goto next;
-            }
-
-            /* XXX make wrapper for token_info? */
-            terminate_string(info.tinfo.manufacturer_id, sizeof info.tinfo.manufacturer_id);
-            terminate_string(info.tinfo.label, sizeof info.tinfo.label);
-            terminate_string(info.tinfo.model, sizeof info.tinfo.model);
-            terminate_string(info.tinfo.serial_number, sizeof info.tinfo.serial_number);
-
-            ret = find_func(pks, &info, input);
-            
-            next:
-            
-            if (ret == 0) {
-                found = 1;
-                goto finish;
-            } else {
-                pakchois_close_session(pks);
-                pks = NULL;
-            }
-        }
-    }
-
-finish:
-    /* final call */
-
-    if (found == 0) {
-        ret = find_func(pks, NULL, input);
-    } else {
-        ret = 0;
-    }
-
-    if (pks != NULL) {
-        pakchois_close_session(pks);
-    }
-   
-    return ret;
+       ck_rv_t rv;
+       int found = 0, x, z, ret;
+       pakchois_session_t *pks = NULL;
+
+       for (x = 0; x < active_providers; x++) {
+               for (z = 0; z < providers[x].nslots; z++) {
+                       struct token_info info;
+
+                       ret = GNUTLS_E_PKCS11_ERROR;
+
+                       rv = pakchois_open_session(providers[x].module,
+                                                  providers[x].slots[z],
+                                                  ((flags & SESSION_WRITE)
+                                                   ? CKF_RW_SESSION : 0) |
+                                                  CKF_SERIAL_SESSION,
+                                                  NULL, NULL, &pks);
+                       if (rv != CKR_OK) {
+                               continue;
+                       }
+
+                       if (pakchois_get_token_info
+                           (providers[x].module, providers[x].slots[z],
+                            &info.tinfo) != CKR_OK) {
+                               goto next;
+                       }
+                       info.sid = providers[x].slots[z];
+                       info.prov = &providers[x];
+
+                       if (pakchois_get_slot_info
+                           (providers[x].module, providers[x].slots[z],
+                            &info.sinfo) != CKR_OK) {
+                               goto next;
+                       }
+
+                       if (flags & SESSION_LOGIN) {
+                               ret = pkcs11_login(pks, &info, NULL);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       return ret;
+                               }
+                       }
+
+                       /* XXX make wrapper for token_info? */
+                       terminate_string(info.tinfo.manufacturer_id,
+                                        sizeof info.tinfo.
+                                        manufacturer_id);
+                       terminate_string(info.tinfo.label,
+                                        sizeof info.tinfo.label);
+                       terminate_string(info.tinfo.model,
+                                        sizeof info.tinfo.model);
+                       terminate_string(info.tinfo.serial_number,
+                                        sizeof info.tinfo.serial_number);
+
+                       ret = find_func(pks, &info, input);
+
+                     next:
+
+                       if (ret == 0) {
+                               found = 1;
+                               goto finish;
+                       } else {
+                               pakchois_close_session(pks);
+                               pks = NULL;
+                       }
+               }
+       }
+
+      finish:
+       /* final call */
+
+       if (found == 0) {
+               ret = find_func(pks, NULL, input);
+       } else {
+               ret = 0;
+       }
+
+       if (pks != NULL) {
+               pakchois_close_session(pks);
+       }
+
+       return ret;
 }
 
-static const charpkcs11_obj_type_to_str(gnutls_pkcs11_obj_type_t type)
+static const char *pkcs11_obj_type_to_str(gnutls_pkcs11_obj_type_t type)
 {
-    switch(type) {
-        case GNUTLS_PKCS11_OBJ_X509_CRT:
-            return "cert";
-        case GNUTLS_PKCS11_OBJ_PUBKEY:
-            return "public";
-        case GNUTLS_PKCS11_OBJ_PRIVKEY:
-            return "private";
-        case GNUTLS_PKCS11_OBJ_SECRET_KEY:
-            return "secretkey";
-        case GNUTLS_PKCS11_OBJ_DATA:
-            return "data";
-        case GNUTLS_PKCS11_OBJ_UNKNOWN:
-        default:
-            return "unknown";
-    }
+       switch (type) {
+       case GNUTLS_PKCS11_OBJ_X509_CRT:
+               return "cert";
+       case GNUTLS_PKCS11_OBJ_PUBKEY:
+               return "public";
+       case GNUTLS_PKCS11_OBJ_PRIVKEY:
+               return "private";
+       case GNUTLS_PKCS11_OBJ_SECRET_KEY:
+               return "secretkey";
+       case GNUTLS_PKCS11_OBJ_DATA:
+               return "data";
+       case GNUTLS_PKCS11_OBJ_UNKNOWN:
+       default:
+               return "unknown";
+       }
 }
 
 /* imports a raw certificate from a token to a pkcs11_obj_t structure.
  */
-static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t crt, const gnutls_datum_t* data, 
-   const gnutls_datum_t * id, const gnutls_datum_t * label, struct ck_token_info* tinfo)
+static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t crt,
+                            const gnutls_datum_t * data,
+                            const gnutls_datum_t * id,
+                            const gnutls_datum_t * label,
+                            struct ck_token_info *tinfo)
 {
-    char *s;
-    int ret;
-
-    switch(class) {
-        case CKO_CERTIFICATE:
-            crt->type = GNUTLS_PKCS11_OBJ_X509_CRT;
-            break;
-        case CKO_PUBLIC_KEY:
-            crt->type = GNUTLS_PKCS11_OBJ_PUBKEY;
-            break;
-        case CKO_PRIVATE_KEY:
-            crt->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
-            break;
-        case CKO_SECRET_KEY:
-            crt->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
-            break;
-        case CKO_DATA:
-            crt->type = GNUTLS_PKCS11_OBJ_DATA;
-            break;
-        default:
-            crt->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
-    }
-
-    if (crt->type != GNUTLS_PKCS11_OBJ_UNKNOWN)
-        strcpy(crt->info.type, pkcs11_obj_type_to_str(crt->type));
-
-    if (data && data->data) {
-        ret = _gnutls_set_datum(&crt->raw, data->data, data->size);
-        if (ret < 0) {
-            gnutls_assert();
-            return ret;
-        }
-    }
-
-    terminate_string(tinfo->manufacturer_id, sizeof tinfo->manufacturer_id);
-    terminate_string(tinfo->label, sizeof tinfo->label);
-    terminate_string(tinfo->model, sizeof tinfo->model);
-    terminate_string(tinfo->serial_number, sizeof tinfo->serial_number);
-
-    /* write data */
-    snprintf(crt->info.manufacturer, sizeof(crt->info.manufacturer), "%s", tinfo->manufacturer_id);
-    snprintf(crt->info.token, sizeof(crt->info.token), "%s", tinfo->label);
-    snprintf(crt->info.model, sizeof(crt->info.model), "%s", tinfo->model);
-    snprintf(crt->info.serial, sizeof(crt->info.serial), "%s", tinfo->serial_number);
-
-    if (label && label->data) {
-        memcpy(crt->info.label, label->data, label->size);
-        crt->info.label[label->size] = 0;
-    }
-
-    if (id && id->data) {
-        s = _gnutls_bin2hex(id->data, id->size, crt->info.id, sizeof(crt->info.id), ":");
-        if (s == NULL) {
-            gnutls_assert();
-            return GNUTLS_E_PKCS11_ERROR;
-        }
-    
-        memmove(crt->info.certid_raw, id->data, id->size);
-        crt->info.certid_raw_size = id->size;
-    }
+       char *s;
+       int ret;
+
+       switch (class) {
+       case CKO_CERTIFICATE:
+               crt->type = GNUTLS_PKCS11_OBJ_X509_CRT;
+               break;
+       case CKO_PUBLIC_KEY:
+               crt->type = GNUTLS_PKCS11_OBJ_PUBKEY;
+               break;
+       case CKO_PRIVATE_KEY:
+               crt->type = GNUTLS_PKCS11_OBJ_PRIVKEY;
+               break;
+       case CKO_SECRET_KEY:
+               crt->type = GNUTLS_PKCS11_OBJ_SECRET_KEY;
+               break;
+       case CKO_DATA:
+               crt->type = GNUTLS_PKCS11_OBJ_DATA;
+               break;
+       default:
+               crt->type = GNUTLS_PKCS11_OBJ_UNKNOWN;
+       }
+
+       if (crt->type != GNUTLS_PKCS11_OBJ_UNKNOWN)
+               strcpy(crt->info.type, pkcs11_obj_type_to_str(crt->type));
 
-    return 0;
+       if (data && data->data) {
+               ret = _gnutls_set_datum(&crt->raw, data->data, data->size);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+       }
+
+       terminate_string(tinfo->manufacturer_id,
+                        sizeof tinfo->manufacturer_id);
+       terminate_string(tinfo->label, sizeof tinfo->label);
+       terminate_string(tinfo->model, sizeof tinfo->model);
+       terminate_string(tinfo->serial_number,
+                        sizeof tinfo->serial_number);
+
+       /* write data */
+       snprintf(crt->info.manufacturer, sizeof(crt->info.manufacturer),
+                "%s", tinfo->manufacturer_id);
+       snprintf(crt->info.token, sizeof(crt->info.token), "%s",
+                tinfo->label);
+       snprintf(crt->info.model, sizeof(crt->info.model), "%s",
+                tinfo->model);
+       snprintf(crt->info.serial, sizeof(crt->info.serial), "%s",
+                tinfo->serial_number);
+
+       if (label && label->data) {
+               memcpy(crt->info.label, label->data, label->size);
+               crt->info.label[label->size] = 0;
+       }
+
+       if (id && id->data) {
+               s = _gnutls_bin2hex(id->data, id->size, crt->info.id,
+                                   sizeof(crt->info.id), ":");
+               if (s == NULL) {
+                       gnutls_assert();
+                       return GNUTLS_E_PKCS11_ERROR;
+               }
+
+               memmove(crt->info.certid_raw, id->data, id->size);
+               crt->info.certid_raw_size = id->size;
+       }
+
+       return 0;
 }
 
-static int pkcs11_obj_import_pubkey(pakchois_session_t *pks, ck_object_handle_t obj,
-    gnutls_pkcs11_obj_t crt, const gnutls_datum_t * id,
-    const gnutls_datum_t* label, struct ck_token_info* tinfo)
+static int pkcs11_obj_import_pubkey(pakchois_session_t * pks,
+                                   ck_object_handle_t obj,
+                                   gnutls_pkcs11_obj_t crt,
+                                   const gnutls_datum_t * id,
+                                   const gnutls_datum_t * label,
+                                   struct ck_token_info *tinfo)
 {
 
-    struct ck_attribute a[4];
-    ck_key_type_t key_type;
-    opaque tmp1[2048];
-    opaque tmp2[2048];
-    int ret;
-    unsigned int tval;
-
-    a[0].type = CKA_KEY_TYPE;
-    a[0].value = &key_type;
-    a[0].value_len = sizeof(key_type);
-
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        switch(key_type) {
-            case CKK_RSA:
-                a[0].type = CKA_MODULUS;
-                a[0].value = tmp1;
-                a[0].value_len = sizeof(tmp1);
-                a[1].type = CKA_PUBLIC_EXPONENT;
-                a[1].value = tmp2;
-                a[1].value_len = sizeof(tmp2);
-
-                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
-
-                    ret = _gnutls_set_datum(&crt->pubkey[0], a[0].value, a[0].value_len);
-
-                    if (ret >= 0)
-                        ret = _gnutls_set_datum(&crt->pubkey[1], a[1].value, a[1].value_len);
-
-                    if (ret < 0) {
-                        gnutls_assert();
-                        _gnutls_free_datum(&crt->pubkey[1]);
-                        _gnutls_free_datum(&crt->pubkey[0]);
-                        return GNUTLS_E_MEMORY_ERROR;
-                    }
-                } else {
-                    gnutls_assert();
-                    return GNUTLS_E_PKCS11_ERROR;
-                }
-                crt->pk_algorithm = GNUTLS_PK_RSA;
-                break;
-            case CKK_DSA:
-                a[0].type = CKA_PRIME;
-                a[0].value = tmp1;
-                a[0].value_len = sizeof(tmp1);
-                a[1].type = CKA_SUBPRIME;
-                a[1].value = tmp2;
-                a[1].value_len = sizeof(tmp2);
-
-                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
-                    ret = _gnutls_set_datum(&crt->pubkey[0], a[0].value, a[0].value_len);
-
-                    if (ret >= 0)
-                        ret = _gnutls_set_datum(&crt->pubkey[1], a[1].value, a[1].value_len);
-
-                    if (ret < 0) {
-                        gnutls_assert();
-                        _gnutls_free_datum(&crt->pubkey[1]);
-                        _gnutls_free_datum(&crt->pubkey[0]);
-                        return GNUTLS_E_MEMORY_ERROR;
-                    }
-                } else {
-                    gnutls_assert();
-                    return GNUTLS_E_PKCS11_ERROR;
-                }
-
-                a[0].type = CKA_BASE;
-                a[0].value = tmp1;
-                a[0].value_len = sizeof(tmp1);
-                a[1].type = CKA_VALUE;
-                a[1].value = tmp2;
-                a[1].value_len = sizeof(tmp2);
-
-                if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
-                    ret = _gnutls_set_datum(&crt->pubkey[2], a[0].value, a[0].value_len);
-
-                    if (ret >= 0)
-                        ret = _gnutls_set_datum(&crt->pubkey[3], a[1].value, a[1].value_len);
-
-                    if (ret < 0) {
-                        gnutls_assert();
-                        _gnutls_free_datum(&crt->pubkey[0]);
-                        _gnutls_free_datum(&crt->pubkey[1]);
-                        _gnutls_free_datum(&crt->pubkey[2]);
-                        _gnutls_free_datum(&crt->pubkey[3]);
-                        return GNUTLS_E_MEMORY_ERROR;
-                    }
-                } else {
-                    gnutls_assert();
-                    return GNUTLS_E_PKCS11_ERROR;
-                }
-                crt->pk_algorithm = GNUTLS_PK_RSA;
-                break;
-            default:
-                gnutls_assert();
-                return GNUTLS_E_UNIMPLEMENTED_FEATURE;
-        }
-    }
+       struct ck_attribute a[4];
+       ck_key_type_t key_type;
+       opaque tmp1[2048];
+       opaque tmp2[2048];
+       int ret;
+       unsigned int tval;
+
+       a[0].type = CKA_KEY_TYPE;
+       a[0].value = &key_type;
+       a[0].value_len = sizeof(key_type);
+
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               switch (key_type) {
+               case CKK_RSA:
+                       a[0].type = CKA_MODULUS;
+                       a[0].value = tmp1;
+                       a[0].value_len = sizeof(tmp1);
+                       a[1].type = CKA_PUBLIC_EXPONENT;
+                       a[1].value = tmp2;
+                       a[1].value_len = sizeof(tmp2);
+
+                       if (pakchois_get_attribute_value(pks, obj, a, 2) ==
+                           CKR_OK) {
+
+                               ret =
+                                   _gnutls_set_datum(&crt->pubkey[0],
+                                                     a[0].value,
+                                                     a[0].value_len);
+
+                               if (ret >= 0)
+                                       ret =
+                                           _gnutls_set_datum(&crt->
+                                                             pubkey[1],
+                                                             a[1].value,
+                                                             a[1].
+                                                             value_len);
+
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[1]);
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[0]);
+                                       return GNUTLS_E_MEMORY_ERROR;
+                               }
+                       } else {
+                               gnutls_assert();
+                               return GNUTLS_E_PKCS11_ERROR;
+                       }
+                       crt->pk_algorithm = GNUTLS_PK_RSA;
+                       break;
+               case CKK_DSA:
+                       a[0].type = CKA_PRIME;
+                       a[0].value = tmp1;
+                       a[0].value_len = sizeof(tmp1);
+                       a[1].type = CKA_SUBPRIME;
+                       a[1].value = tmp2;
+                       a[1].value_len = sizeof(tmp2);
+
+                       if (pakchois_get_attribute_value(pks, obj, a, 2) ==
+                           CKR_OK) {
+                               ret =
+                                   _gnutls_set_datum(&crt->pubkey[0],
+                                                     a[0].value,
+                                                     a[0].value_len);
+
+                               if (ret >= 0)
+                                       ret =
+                                           _gnutls_set_datum(&crt->
+                                                             pubkey[1],
+                                                             a[1].value,
+                                                             a[1].
+                                                             value_len);
+
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[1]);
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[0]);
+                                       return GNUTLS_E_MEMORY_ERROR;
+                               }
+                       } else {
+                               gnutls_assert();
+                               return GNUTLS_E_PKCS11_ERROR;
+                       }
+
+                       a[0].type = CKA_BASE;
+                       a[0].value = tmp1;
+                       a[0].value_len = sizeof(tmp1);
+                       a[1].type = CKA_VALUE;
+                       a[1].value = tmp2;
+                       a[1].value_len = sizeof(tmp2);
+
+                       if (pakchois_get_attribute_value(pks, obj, a, 2) ==
+                           CKR_OK) {
+                               ret =
+                                   _gnutls_set_datum(&crt->pubkey[2],
+                                                     a[0].value,
+                                                     a[0].value_len);
+
+                               if (ret >= 0)
+                                       ret =
+                                           _gnutls_set_datum(&crt->
+                                                             pubkey[3],
+                                                             a[1].value,
+                                                             a[1].
+                                                             value_len);
+
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[0]);
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[1]);
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[2]);
+                                       _gnutls_free_datum(&crt->
+                                                          pubkey[3]);
+                                       return GNUTLS_E_MEMORY_ERROR;
+                               }
+                       } else {
+                               gnutls_assert();
+                               return GNUTLS_E_PKCS11_ERROR;
+                       }
+                       crt->pk_algorithm = GNUTLS_PK_RSA;
+                       break;
+               default:
+                       gnutls_assert();
+                       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+               }
+       }
 
-    /* read key usage flags */
-    a[0].type = CKA_ENCRYPT;
-    a[0].value = &tval;
-    a[0].value_len = sizeof(tval);
+       /* read key usage flags */
+       a[0].type = CKA_ENCRYPT;
+       a[0].value = &tval;
+       a[0].value_len = sizeof(tval);
 
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        if (tval != 0) {
-            crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
-        }
-    }
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               if (tval != 0) {
+                       crt->key_usage |= GNUTLS_KEY_DATA_ENCIPHERMENT;
+               }
+       }
 
-    a[0].type = CKA_VERIFY;
-    a[0].value = &tval;
-    a[0].value_len = sizeof(tval);
+       a[0].type = CKA_VERIFY;
+       a[0].value = &tval;
+       a[0].value_len = sizeof(tval);
 
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        if (tval != 0) {
-            crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE| \
-            GNUTLS_KEY_KEY_CERT_SIGN|GNUTLS_KEY_CRL_SIGN|GNUTLS_KEY_NON_REPUDIATION;
-        }
-    }
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               if (tval != 0) {
+                       crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
+                           GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
+                           | GNUTLS_KEY_NON_REPUDIATION;
+               }
+       }
 
-    a[0].type = CKA_VERIFY_RECOVER;
-    a[0].value = &tval;
-    a[0].value_len = sizeof(tval);
+       a[0].type = CKA_VERIFY_RECOVER;
+       a[0].value = &tval;
+       a[0].value_len = sizeof(tval);
 
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        if (tval != 0) {
-            crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE| \
-            GNUTLS_KEY_KEY_CERT_SIGN|GNUTLS_KEY_CRL_SIGN|GNUTLS_KEY_NON_REPUDIATION;
-        }
-    }
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               if (tval != 0) {
+                       crt->key_usage |= GNUTLS_KEY_DIGITAL_SIGNATURE |
+                           GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN
+                           | GNUTLS_KEY_NON_REPUDIATION;
+               }
+       }
 
-    a[0].type = CKA_DERIVE;
-    a[0].value = &tval;
-    a[0].value_len = sizeof(tval);
+       a[0].type = CKA_DERIVE;
+       a[0].value = &tval;
+       a[0].value_len = sizeof(tval);
 
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        if (tval != 0) {
-            crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
-        }
-    }
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               if (tval != 0) {
+                       crt->key_usage |= GNUTLS_KEY_KEY_AGREEMENT;
+               }
+       }
 
-    a[0].type = CKA_WRAP;
-    a[0].value = &tval;
-    a[0].value_len = sizeof(tval);
+       a[0].type = CKA_WRAP;
+       a[0].value = &tval;
+       a[0].value_len = sizeof(tval);
 
-    if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-        if (tval != 0) {
-            crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
-        }
-    }
+       if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+               if (tval != 0) {
+                       crt->key_usage |= GNUTLS_KEY_KEY_ENCIPHERMENT;
+               }
+       }
 
-    return pkcs11_obj_import(CKO_PUBLIC_KEY, crt, NULL, id, label, tinfo);
+       return pkcs11_obj_import(CKO_PUBLIC_KEY, crt, NULL, id, label,
+                                tinfo);
 }
 
-ck_object_class_t pkcs11_strtype_to_class(const chartype)
+ck_object_class_t pkcs11_strtype_to_class(const char *type)
 {
-    ck_object_class_t class;
-    
-    if (strcmp(type, "cert") == 0) {
-        class = CKO_CERTIFICATE;
-    } else if (strcmp(type, "public") == 0) {
-        class = CKO_PUBLIC_KEY;
-    } else if (strcmp(type, "private") == 0) {
-        class = CKO_PRIVATE_KEY;
-    } else if (strcmp(type, "secretkey") == 0) {
-        class = CKO_SECRET_KEY;
-    } else if (strcmp(type, "data") == 0) {
-        class = CKO_DATA;
-    } else {
-        class = -1;
-    }
-    
-    return class;
+       ck_object_class_t class;
+
+       if (strcmp(type, "cert") == 0) {
+               class = CKO_CERTIFICATE;
+       } else if (strcmp(type, "public") == 0) {
+               class = CKO_PUBLIC_KEY;
+       } else if (strcmp(type, "private") == 0) {
+               class = CKO_PRIVATE_KEY;
+       } else if (strcmp(type, "secretkey") == 0) {
+               class = CKO_SECRET_KEY;
+       } else if (strcmp(type, "data") == 0) {
+               class = CKO_DATA;
+       } else {
+               class = -1;
+       }
+
+       return class;
 }
 
 
-static int find_obj_url(pakchois_session_t *pks, struct token_info *info, void* input)
+static int find_obj_url(pakchois_session_t * pks, struct token_info *info,
+                       void *input)
 {
-    struct url_find_data_st* find_data = input;
-    struct ck_attribute a[4];
-    ck_object_class_t class = -1;
-    ck_certificate_type_t type = -1;
-    ck_rv_t rv;
-    ck_object_handle_t obj;
-    unsigned long count, a_vals;
-    int found = 0, ret;
-    opaque* cert_data = NULL;
-    char label_tmp[PKCS11_LABEL_SIZE];
-    
-    if (info == NULL) { /* we don't support multiple calls */
-        gnutls_assert();
-        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-    
-    /* do not bother reading the token if basic fields do not match
-     */
-    if (pkcs11_token_matches_info( &find_data->crt->info, &info->tinfo) < 0) {
+       struct url_find_data_st *find_data = input;
+       struct ck_attribute a[4];
+       ck_object_class_t class = -1;
+       ck_certificate_type_t type = -1;
+       ck_rv_t rv;
+       ck_object_handle_t obj;
+       unsigned long count, a_vals;
+       int found = 0, ret;
+       opaque *cert_data = NULL;
+       char label_tmp[PKCS11_LABEL_SIZE];
+
+       if (info == NULL) {     /* we don't support multiple calls */
                gnutls_assert();
                return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
        }
 
-    if (find_data->crt->info.type[0] != 0) {
-        class = pkcs11_strtype_to_class(find_data->crt->info.type);
-        if (class == CKO_CERTIFICATE)
-            type = CKC_X_509;
+       /* do not bother reading the token if basic fields do not match
+        */
+       if (pkcs11_token_matches_info(&find_data->crt->info, &info->tinfo)
+           < 0) {
+               gnutls_assert();
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
 
-        if (class == -1) {
-            gnutls_assert();
-            return GNUTLS_E_INVALID_REQUEST;
-        }
-    }
-
-    /* search the token for the id */
-    
-    cert_data = gnutls_malloc(MAX_CERT_SIZE);
-    if (cert_data == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_MEMORY_ERROR;
-    }
-    
-    /* Find objects with given class and type */
-
-    a[0].type = CKA_ID;
-    a[0].value = find_data->crt->info.certid_raw;
-    a[0].value_len = find_data->crt->info.certid_raw_size;
-    
-    a_vals = 1;
-
-    if (class != -1) {
-        a[a_vals].type = CKA_CLASS;
-        a[a_vals].value = &class;
-        a[a_vals].value_len = sizeof class;
-        a_vals++;
-    }
-    
-    if (type != -1) {
-        a[a_vals].type = CKA_CERTIFICATE_TYPE;
-        a[a_vals].value = &type;
-        a[a_vals].value_len = sizeof type;
-        a_vals++;
-    }
-
-    rv = pakchois_find_objects_init(pks, a, a_vals);
-    if (rv != CKR_OK) {
-        gnutls_assert();
-        _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
-        ret = pkcs11_rv_to_err(rv);
-        goto cleanup;
-    }
-
-    while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
-           && count == 1) {
-
-        a[0].type = CKA_VALUE;
-        a[0].value = cert_data;
-        a[0].value_len = MAX_CERT_SIZE;
-        a[1].type = CKA_LABEL;
-        a[1].value = label_tmp;
-        a[1].value_len = sizeof(label_tmp);
-
-        if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
-            gnutls_datum_t id = { find_data->crt->info.certid_raw, find_data->crt->info.certid_raw_size };
-            gnutls_datum_t data = { a[0].value, a[0].value_len };
-            gnutls_datum_t label = { a[1].value, a[1].value_len };
-            
-            if (class == CKO_PUBLIC_KEY) {
-                ret = pkcs11_obj_import_pubkey(pks, obj, find_data->crt, &id, &label, &info->tinfo);
-            } else {
-                ret = pkcs11_obj_import(class, find_data->crt, &data, &id, &label, &info->tinfo);
-            }
-            if (ret < 0) {
-                gnutls_assert();
-                goto cleanup;
-            }
-
-            found = 1;
-            break;
-        }
-        else {
-            _gnutls_debug_log("pk11: Skipped cert, missing attrs.\n");
+       if (find_data->crt->info.type[0] != 0) {
+               class = pkcs11_strtype_to_class(find_data->crt->info.type);
+               if (class == CKO_CERTIFICATE)
+                       type = CKC_X_509;
+
+               if (class == -1) {
+                       gnutls_assert();
+                       return GNUTLS_E_INVALID_REQUEST;
+               }
+       }
+
+       /* search the token for the id */
+
+       cert_data = gnutls_malloc(MAX_CERT_SIZE);
+       if (cert_data == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       /* Find objects with given class and type */
+
+       a[0].type = CKA_ID;
+       a[0].value = find_data->crt->info.certid_raw;
+       a[0].value_len = find_data->crt->info.certid_raw_size;
+
+       a_vals = 1;
+
+       if (class != -1) {
+               a[a_vals].type = CKA_CLASS;
+               a[a_vals].value = &class;
+               a[a_vals].value_len = sizeof class;
+               a_vals++;
+       }
+
+       if (type != -1) {
+               a[a_vals].type = CKA_CERTIFICATE_TYPE;
+               a[a_vals].value = &type;
+               a[a_vals].value_len = sizeof type;
+               a_vals++;
+       }
+
+       rv = pakchois_find_objects_init(pks, a, a_vals);
+       if (rv != CKR_OK) {
+               gnutls_assert();
+               _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
+               ret = pkcs11_rv_to_err(rv);
+               goto cleanup;
+       }
+
+       while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
+              && count == 1) {
+
+               a[0].type = CKA_VALUE;
+               a[0].value = cert_data;
+               a[0].value_len = MAX_CERT_SIZE;
+               a[1].type = CKA_LABEL;
+               a[1].value = label_tmp;
+               a[1].value_len = sizeof(label_tmp);
+
+               if (pakchois_get_attribute_value(pks, obj, a, 2) == CKR_OK) {
+                       gnutls_datum_t id =
+                           { find_data->crt->info.certid_raw,
+                   find_data->crt->info.certid_raw_size };
+                       gnutls_datum_t data =
+                           { a[0].value, a[0].value_len };
+                       gnutls_datum_t label =
+                           { a[1].value, a[1].value_len };
+
+                       if (class == CKO_PUBLIC_KEY) {
+                               ret =
+                                   pkcs11_obj_import_pubkey(pks, obj,
+                                                            find_data->
+                                                            crt, &id,
+                                                            &label,
+                                                            &info->tinfo);
+                       } else {
+                               ret =
+                                   pkcs11_obj_import(class,
+                                                     find_data->crt,
+                                                     &data, &id, &label,
+                                                     &info->tinfo);
+                       }
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+
+                       found = 1;
+                       break;
+               } else {
+                       _gnutls_debug_log
+                           ("pk11: Skipped cert, missing attrs.\n");
+               }
+       }
+
+       if (found == 0) {
+               gnutls_assert();
+               ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       } else {
+               ret = 0;
+       }
+
+      cleanup:
+       gnutls_free(cert_data);
+       pakchois_find_objects_final(pks);
+
+       return ret;
+}
+
+inline static unsigned int pkcs11_obj_flags_to_int(unsigned int flags)
+{
+        switch(flags) {
+                case GNUTLS_PKCS11_OBJ_FLAG_LOGIN:
+                        return SESSION_LOGIN;
+                default:
+                        return 0;
         }
-    }
-
-    if (found == 0) {
-        gnutls_assert();
-        ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    } else {
-        ret = 0;
-    }
-
-cleanup:
-    gnutls_free(cert_data);
-    pakchois_find_objects_final(pks);
-    
-    return ret;
 }
 
 /**
  * gnutls_pkcs11_privkey_import_url:
  * @cert: The structure to store the parsed certificate
  * @url: a PKCS 11 url identifying the key
+ * @flags: One of GNUTLS_PKCS11_OBJ_* flags
  *
  * This function will "import" a PKCS 11 URL identifying a certificate
  * key to the #gnutls_pkcs11_obj_t structure. This does not involve any
@@ -1397,58 +1541,62 @@ cleanup:
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char * url)
+int gnutls_pkcs11_obj_import_url(gnutls_pkcs11_obj_t cert, const char *url,
+        unsigned int flags)
 {
-    int ret;
-    struct url_find_data_st find_data;
-    
-    /* fill in the find data structure */
-    find_data.crt = cert;
-
-    ret = pkcs11_url_to_info(url, &cert->info);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = _pkcs11_traverse_tokens(find_obj_url, &find_data, 0);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-    
-    return 0;
+       int ret;
+       struct url_find_data_st find_data;
+
+       /* fill in the find data structure */
+       find_data.crt = cert;
+
+       ret = pkcs11_url_to_info(url, &cert->info);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret = _pkcs11_traverse_tokens(find_obj_url, &find_data, pkcs11_obj_flags_to_int(flags));
+
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
 }
 
 struct token_num {
-    struct pkcs11_url_info info;
-    unsigned int seq; /* which one we are looking for */
-    unsigned int current; /* which one are we now */
+       struct pkcs11_url_info info;
+       unsigned int seq;       /* which one we are looking for */
+       unsigned int current;   /* which one are we now */
 };
 
-static int find_token_num(pakchois_session_t *pks, struct token_info *tinfo, void* input)
+static int find_token_num(pakchois_session_t * pks,
+                         struct token_info *tinfo, void *input)
 {
-    struct token_num* find_data = input;
+       struct token_num *find_data = input;
 
-    if (tinfo == NULL) { /* we don't support multiple calls */
-        gnutls_assert();
-        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
+       if (tinfo == NULL) {    /* we don't support multiple calls */
+               gnutls_assert();
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
 
-    if (find_data->current == find_data->seq) {
-        strcpy(find_data->info.manufacturer, tinfo->tinfo.manufacturer_id);
-        strcpy(find_data->info.token, tinfo->tinfo.label);
-        strcpy(find_data->info.model, tinfo->tinfo.model);
-        strcpy(find_data->info.serial, tinfo->tinfo.serial_number);
+       if (find_data->current == find_data->seq) {
+               strcpy(find_data->info.manufacturer,
+                      tinfo->tinfo.manufacturer_id);
+               strcpy(find_data->info.token, tinfo->tinfo.label);
+               strcpy(find_data->info.model, tinfo->tinfo.model);
+               strcpy(find_data->info.serial, tinfo->tinfo.serial_number);
 
-        return 0;
-    }
+               return 0;
+       }
 
-    find_data->current++;
-    /* search the token for the id */
+       find_data->current++;
+       /* search the token for the id */
 
 
-    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */
+       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;   /* non zero is enough */
 }
 
 /**
@@ -1463,27 +1611,27 @@ static int find_token_num(pakchois_session_t *pks, struct token_info *tinfo, voi
  * if the sequence number exceeds the available tokens, otherwise a negative error value.
  **/
 
-int gnutls_pkcs11_token_get_url (unsigned int seq, char** url)
+int gnutls_pkcs11_token_get_url(unsigned int seq, char **url)
 {
-    int ret;
-    struct token_num tn;
-
-    memset(&tn, 0, sizeof(tn));
-    tn.seq = seq;
-    
-    ret = _pkcs11_traverse_tokens(find_token_num, &tn, 0);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = pkcs11_info_to_url(&tn.info, url);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    return 0;
+       int ret;
+       struct token_num tn;
+
+       memset(&tn, 0, sizeof(tn));
+       tn.seq = seq;
+
+       ret = _pkcs11_traverse_tokens(find_token_num, &tn, 0);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret = pkcs11_info_to_url(&tn.info, url);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
 
 }
 
@@ -1499,49 +1647,51 @@ int gnutls_pkcs11_token_get_url (unsigned int seq, char** url)
  *
  * Returns: zero on success or a negative value on error.
  **/
-int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t ttype, void* output, size_t *output_size)
+int gnutls_pkcs11_token_get_info(const char *url,
+                                gnutls_pkcs11_token_info_t ttype,
+                                void *output, size_t * output_size)
 {
-    const char* str;
-    size_t len;
-    struct pkcs11_url_info info;
-    int ret;
-
-    ret = pkcs11_url_to_info(url, &info);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    switch(ttype) {
-        case GNUTLS_PKCS11_TOKEN_LABEL:
-            str = info.token;
-            break;
-        case GNUTLS_PKCS11_TOKEN_SERIAL:
-            str = info.serial;
-            break;
-        case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
-            str = info.manufacturer;
-            break;
-        case GNUTLS_PKCS11_TOKEN_MODEL:
-            str = info.model;
-            break;
-        default:
-            gnutls_assert();
-            return GNUTLS_E_INVALID_REQUEST;
-    }
-
-    len = strlen(str);
-
-    if (len+1>*output_size) {
-        *output_size = len+1;
-        return GNUTLS_E_SHORT_MEMORY_BUFFER;
-    }
-
-    strcpy(output, str);
-
-    *output_size = len;
-
-    return 0;
+       const char *str;
+       size_t len;
+       struct pkcs11_url_info info;
+       int ret;
+
+       ret = pkcs11_url_to_info(url, &info);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       switch (ttype) {
+       case GNUTLS_PKCS11_TOKEN_LABEL:
+               str = info.token;
+               break;
+       case GNUTLS_PKCS11_TOKEN_SERIAL:
+               str = info.serial;
+               break;
+       case GNUTLS_PKCS11_TOKEN_MANUFACTURER:
+               str = info.manufacturer;
+               break;
+       case GNUTLS_PKCS11_TOKEN_MODEL:
+               str = info.model;
+               break;
+       default:
+               gnutls_assert();
+               return GNUTLS_E_INVALID_REQUEST;
+       }
+
+       len = strlen(str);
+
+       if (len + 1 > *output_size) {
+               *output_size = len + 1;
+               return GNUTLS_E_SHORT_MEMORY_BUFFER;
+       }
+
+       strcpy(output, str);
+
+       *output_size = len;
+
+       return 0;
 }
 
 /**
@@ -1554,17 +1704,17 @@ int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t tty
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t cert, char ** url)
+int gnutls_pkcs11_obj_export_url(gnutls_pkcs11_obj_t cert, char **url)
 {
-int ret;
-
-    ret = pkcs11_info_to_url(&cert->info, url);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-    
-    return 0;
+       int ret;
+
+       ret = pkcs11_info_to_url(&cert->info, url);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
 }
 
 /**
@@ -1576,510 +1726,559 @@ int ret;
  *
  * Returns: The type of the certificate.
  **/
-gnutls_pkcs11_obj_type_t gnutls_pkcs11_obj_get_type (gnutls_pkcs11_obj_t obj)
+gnutls_pkcs11_obj_type_t gnutls_pkcs11_obj_get_type(gnutls_pkcs11_obj_t
+                                                   obj)
 {
-    return obj->type;
+       return obj->type;
 }
 
 struct pkey_list {
-    gnutls_buffer_st *key_ids;
-    size_t key_ids_size;
+       gnutls_buffer_st *key_ids;
+       size_t key_ids_size;
 };
 
-int pkcs11_login(pakchois_session_t *pks, struct token_info *info, token_creds_st* creds)
+int pkcs11_login(pakchois_session_t * pks, struct token_info *info,
+                token_creds_st * creds)
 {
-    int attempt = 0, ret;
-    ck_rv_t rv;
-    int pin_len;
-
-    if (pakchois_get_token_info(info->prov->module, info->sid, &info->tinfo) != CKR_OK) {
-        gnutls_assert();
-        _gnutls_debug_log( "pk11: GetTokenInfo failed\n");
-        return GNUTLS_E_PKCS11_ERROR;
-    }
-
-    if ((info->tinfo.flags & CKF_LOGIN_REQUIRED) == 0) {
-        gnutls_assert();
-        _gnutls_debug_log( "pk11: No login required.\n");
-        return 0;
-    }
-
-    /* For a token with a "protected" (out-of-band) authentication
-     * path, calling login with a NULL username is all that is
-     * required. */
-    if (info->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
-        if (pakchois_login(pks, CKU_USER, NULL, 0) == CKR_OK) {
-            return 0;
-        }
-        else {
-            gnutls_assert();
-            _gnutls_debug_log( "pk11: Protected login failed.\n");
-            return GNUTLS_E_PKCS11_ERROR;
-        }
-    }
-
-    /* Otherwise, PIN entry is necessary for login, so fail if there's
-     * no callback. */
-    if (!pin_func && !creds) {
-        gnutls_assert();
-        _gnutls_debug_log("pk11: No pin callback but login required.\n");
-        return GNUTLS_E_PKCS11_ERROR;
-    }
-
-    terminate_string(info->sinfo.slot_description, sizeof info->sinfo.slot_description);
-
-    do {
-        char pin[GNUTLS_PKCS11_MAX_PIN_LEN];
-        unsigned int flags = 0;
-
-        /* If login has been attempted once already, check the token
-         * status again, the flags might change. */
-        if (attempt) {
-            if (pakchois_get_token_info(info->prov->module, info->sid,
-                                        &info->tinfo) != CKR_OK) {
-                gnutls_assert();
-                _gnutls_debug_log( "pk11: GetTokenInfo failed\n");
-                return GNUTLS_E_PKCS11_ERROR;
-            }
-        }
-
-        if (creds != NULL && creds->pin_size > 0 && 
-            !(info->tinfo.flags & CKF_USER_PIN_FINAL_TRY)) {
-
-            memcpy(pin, creds->pin, creds->pin_size);
-            pin_len = creds->pin_size;
-            
-            ret = 0;
-        } else {
-            if (info->tinfo.flags & CKF_USER_PIN_COUNT_LOW)
-                flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
-            if (info->tinfo.flags & CKF_USER_PIN_FINAL_TRY)
-                flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
-
-            terminate_string(info->tinfo.label, sizeof info->tinfo.label);
-
-            ret = pin_func(pin_data, attempt++,
-                             (char *)info->sinfo.slot_description,
-                             (char *)info->tinfo.label, flags, pin, sizeof(pin));
-            if (ret < 0 && ret != GNUTLS_E_PKCS11_PIN_SAVE) {
-                gnutls_assert();
-                return GNUTLS_E_PKCS11_PIN_ERROR;
-            }
-            pin_len = strlen(pin);
-            
-        }
+       int attempt = 0, ret;
+       ck_rv_t rv;
+       int pin_len;
 
-        rv = pakchois_login(pks, CKU_USER, (unsigned char *)pin, pin_len);
+       if (pakchois_get_token_info
+           (info->prov->module, info->sid, &info->tinfo) != CKR_OK) {
+               gnutls_assert();
+               _gnutls_debug_log("pk11: GetTokenInfo failed\n");
+               return GNUTLS_E_PKCS11_ERROR;
+       }
 
-        if (ret == GNUTLS_E_PKCS11_PIN_SAVE && creds && (rv==CKR_OK||rv==CKR_USER_ALREADY_LOGGED_IN)) {
-                memcpy(creds->pin, pin, pin_len);
-                creds->pin_size = pin_len;
-        }
+       if ((info->tinfo.flags & CKF_LOGIN_REQUIRED) == 0) {
+               gnutls_assert();
+               _gnutls_debug_log("pk11: No login required.\n");
+               return 0;
+       }
 
-        /* Try to scrub the pin off the stack.  Clever compilers will
-         * probably optimize this away, oh well. */
-        memset(pin, 0, sizeof pin);
-    } while (rv == CKR_PIN_INCORRECT);
+       /* For a token with a "protected" (out-of-band) authentication
+        * path, calling login with a NULL username is all that is
+        * required. */
+       if (info->tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
+               if (pakchois_login(pks, CKU_USER, NULL, 0) == CKR_OK) {
+                       return 0;
+               } else {
+                       gnutls_assert();
+                       _gnutls_debug_log
+                           ("pk11: Protected login failed.\n");
+                       return GNUTLS_E_PKCS11_ERROR;
+               }
+       }
 
-    _gnutls_debug_log("pk11: Login result = %lu\n", rv);
+       /* Otherwise, PIN entry is necessary for login, so fail if there's
+        * no callback. */
+       if (!pin_func && !creds) {
+               gnutls_assert();
+               _gnutls_debug_log
+                   ("pk11: No pin callback but login required.\n");
+               return GNUTLS_E_PKCS11_ERROR;
+       }
 
-    return (rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err(rv);
+       terminate_string(info->sinfo.slot_description,
+                        sizeof info->sinfo.slot_description);
+
+       do {
+               char pin[GNUTLS_PKCS11_MAX_PIN_LEN];
+               unsigned int flags = 0;
+
+               /* If login has been attempted once already, check the token
+                * status again, the flags might change. */
+               if (attempt) {
+                       if (pakchois_get_token_info
+                           (info->prov->module, info->sid,
+                            &info->tinfo) != CKR_OK) {
+                               gnutls_assert();
+                               _gnutls_debug_log
+                                   ("pk11: GetTokenInfo failed\n");
+                               return GNUTLS_E_PKCS11_ERROR;
+                       }
+               }
+
+               if (creds != NULL && creds->pin_size > 0 &&
+                   !(info->tinfo.flags & CKF_USER_PIN_FINAL_TRY)) {
+
+                       memcpy(pin, creds->pin, creds->pin_size);
+                       pin_len = creds->pin_size;
+
+                       ret = 0;
+               } else {
+                       if (info->tinfo.flags & CKF_USER_PIN_COUNT_LOW)
+                               flags |= GNUTLS_PKCS11_PIN_COUNT_LOW;
+                       if (info->tinfo.flags & CKF_USER_PIN_FINAL_TRY)
+                               flags |= GNUTLS_PKCS11_PIN_FINAL_TRY;
+
+                       terminate_string(info->tinfo.label,
+                                        sizeof info->tinfo.label);
+
+                       ret = pin_func(pin_data, attempt++,
+                                      (char *) info->sinfo.
+                                      slot_description,
+                                      (char *) info->tinfo.label, flags,
+                                      pin, sizeof(pin));
+                       if (ret < 0 && ret != GNUTLS_E_PKCS11_PIN_SAVE) {
+                               gnutls_assert();
+                               return GNUTLS_E_PKCS11_PIN_ERROR;
+                       }
+                       pin_len = strlen(pin);
+
+               }
+
+               rv = pakchois_login(pks, CKU_USER, (unsigned char *) pin,
+                                   pin_len);
+
+               if (ret == GNUTLS_E_PKCS11_PIN_SAVE && creds
+                   && (rv == CKR_OK
+                       || rv == CKR_USER_ALREADY_LOGGED_IN)) {
+                       memcpy(creds->pin, pin, pin_len);
+                       creds->pin_size = pin_len;
+               }
+
+               /* Try to scrub the pin off the stack.  Clever compilers will
+                * probably optimize this away, oh well. */
+               memset(pin, 0, sizeof pin);
+       } while (rv == CKR_PIN_INCORRECT);
+
+       _gnutls_debug_log("pk11: Login result = %lu\n", rv);
+
+       return (rv == CKR_OK
+               || rv ==
+               CKR_USER_ALREADY_LOGGED_IN) ? 0 : pkcs11_rv_to_err(rv);
 }
 
-static int find_privkeys(pakchois_session_t *pks, struct token_info* info, struct pkey_list *list)
+static int find_privkeys(pakchois_session_t * pks, struct token_info *info,
+                        struct pkey_list *list)
 {
-    struct ck_attribute a[3];
-    ck_object_class_t class;
-    ck_rv_t rv;
-    ck_object_handle_t obj;
-    unsigned long count, current;
-    char certid_tmp[PKCS11_ID_SIZE];
-
-    class = CKO_PRIVATE_KEY;
-
-    /* Find an object with private key class and a certificate ID
-     * which matches the certificate. */
-    /* FIXME: also match the cert subject. */
-    a[0].type = CKA_CLASS;
-    a[0].value = &class;
-    a[0].value_len = sizeof class;
-
-    rv = pakchois_find_objects_init(pks, a, 1);
-    if (rv != CKR_OK) {
-        gnutls_assert();
-        return pkcs11_rv_to_err(rv);
-    }
-
-    list->key_ids_size = 0;
-    while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
-           && count == 1) {
-        list->key_ids_size++;
-    }
-
-    pakchois_find_objects_final(pks);
-
-    if (list->key_ids_size == 0) {
-        gnutls_assert();
-        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-
-    list->key_ids = gnutls_malloc(sizeof(gnutls_buffer_st)*list->key_ids_size);
-    if (list->key_ids == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_MEMORY_ERROR;
-    }
-
-    /* actual search */
-    a[0].type = CKA_CLASS;
-    a[0].value = &class;
-    a[0].value_len = sizeof class;
-
-    rv = pakchois_find_objects_init(pks, a, 1);
-    if (rv != CKR_OK) {
-        gnutls_assert();
-        return pkcs11_rv_to_err(rv);
-    }
-
-    current = 0;
-    while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
-           && count == 1) {
-
-        a[0].type = CKA_ID;
-        a[0].value = certid_tmp;
-        a[0].value_len = sizeof(certid_tmp);
-
-        _gnutls_buffer_init(&list->key_ids[current]);
-
-        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-            _gnutls_buffer_append_data(&list->key_ids[current], a[0].value, a[0].value_len);
-            current++;
-        }
+       struct ck_attribute a[3];
+       ck_object_class_t class;
+       ck_rv_t rv;
+       ck_object_handle_t obj;
+       unsigned long count, current;
+       char certid_tmp[PKCS11_ID_SIZE];
+
+       class = CKO_PRIVATE_KEY;
+
+       /* Find an object with private key class and a certificate ID
+        * which matches the certificate. */
+       /* FIXME: also match the cert subject. */
+       a[0].type = CKA_CLASS;
+       a[0].value = &class;
+       a[0].value_len = sizeof class;
+
+       rv = pakchois_find_objects_init(pks, a, 1);
+       if (rv != CKR_OK) {
+               gnutls_assert();
+               return pkcs11_rv_to_err(rv);
+       }
+
+       list->key_ids_size = 0;
+       while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
+              && count == 1) {
+               list->key_ids_size++;
+       }
+
+       pakchois_find_objects_final(pks);
+
+       if (list->key_ids_size == 0) {
+               gnutls_assert();
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+
+       list->key_ids =
+           gnutls_malloc(sizeof(gnutls_buffer_st) * list->key_ids_size);
+       if (list->key_ids == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+
+       /* actual search */
+       a[0].type = CKA_CLASS;
+       a[0].value = &class;
+       a[0].value_len = sizeof class;
+
+       rv = pakchois_find_objects_init(pks, a, 1);
+       if (rv != CKR_OK) {
+               gnutls_assert();
+               return pkcs11_rv_to_err(rv);
+       }
+
+       current = 0;
+       while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
+              && count == 1) {
+
+               a[0].type = CKA_ID;
+               a[0].value = certid_tmp;
+               a[0].value_len = sizeof(certid_tmp);
 
-        if (current > list->key_ids_size)
-            break;
-    }
+               _gnutls_buffer_init(&list->key_ids[current]);
 
-    pakchois_find_objects_final(pks);
+               if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+                       _gnutls_buffer_append_data(&list->key_ids[current],
+                                                  a[0].value,
+                                                  a[0].value_len);
+                       current++;
+               }
 
-    list->key_ids_size = current-1;
+               if (current > list->key_ids_size)
+                       break;
+       }
 
-    return 0;
+       pakchois_find_objects_final(pks);
+
+       list->key_ids_size = current - 1;
+
+       return 0;
 }
 
 /* Recover certificate list from tokens */
 
 
-static int find_objs(pakchois_session_t *pks, struct token_info *info, void* input)
+static int find_objs(pakchois_session_t * pks, struct token_info *info,
+                    void *input)
 {
-    struct crt_find_data_st* find_data = input;
-    struct ck_attribute a[4];
-    ck_object_class_t class=-1;
-    ck_certificate_type_t type=-1;
-    unsigned int trusted;
-    ck_rv_t rv;
-    ck_object_handle_t obj;
-    unsigned long count;
-    opaque *cert_data;
-    char certid_tmp[PKCS11_ID_SIZE];
-    char label_tmp[PKCS11_LABEL_SIZE];
-    int ret, i;
-    struct pkey_list plist; /* private key holder */
-    int tot_values = 0;
-
-    if (info == NULL) { /* final call */
-        if (find_data->current <= *find_data->n_list)
-            ret = 0;
-        else
-            ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
-
-        *find_data->n_list = find_data->current;
-        
-        return ret;
-    }
-
-    /* do not bother reading the token if basic fields do not match
-     */
-    if (pkcs11_token_matches_info( &find_data->info, &info->tinfo) < 0) {
+       struct crt_find_data_st *find_data = input;
+       struct ck_attribute a[4];
+       ck_object_class_t class = -1;
+       ck_certificate_type_t type = -1;
+       unsigned int trusted;
+       ck_rv_t rv;
+       ck_object_handle_t obj;
+       unsigned long count;
+       opaque *cert_data;
+       char certid_tmp[PKCS11_ID_SIZE];
+       char label_tmp[PKCS11_LABEL_SIZE];
+       int ret, i;
+       struct pkey_list plist; /* private key holder */
+       int tot_values = 0;
+
+       if (info == NULL) {     /* final call */
+               if (find_data->current <= *find_data->n_list)
+                       ret = 0;
+               else
+                       ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
+
+               *find_data->n_list = find_data->current;
+
+               return ret;
+       }
+
+       /* do not bother reading the token if basic fields do not match
+        */
+       if (pkcs11_token_matches_info(&find_data->info, &info->tinfo) < 0) {
                gnutls_assert();
                return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
        }
 
-    if (find_data->info.type[0] != 0) {
-        class = pkcs11_strtype_to_class(find_data->info.type);
-        if (class == CKO_CERTIFICATE)
-            type = CKC_X_509;
-        else
-            type = -1;
+       if (find_data->info.type[0] != 0) {
+               class = pkcs11_strtype_to_class(find_data->info.type);
+               if (class == CKO_CERTIFICATE)
+                       type = CKC_X_509;
+               else
+                       type = -1;
+
+               if (class == -1) {
+                       gnutls_assert();
+                       return GNUTLS_E_INVALID_REQUEST;
+               }
+       }
 
-        if (class == -1) {
-            gnutls_assert();
-            return GNUTLS_E_INVALID_REQUEST;
-        }
-    }
-    
 
-    memset(&plist, 0, sizeof(plist));
+       memset(&plist, 0, sizeof(plist));
+
+       if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+               ret = pkcs11_login(pks, info, NULL);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               ret = find_privkeys(pks, info, &plist);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+
+               if (plist.key_ids_size == 0) {
+                       gnutls_assert();
+                       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+               }
+       } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL ||
+                  find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) {
+               ret = pkcs11_login(pks, info, NULL);
+               if (ret < 0) {
+                       gnutls_assert();
+                       return ret;
+               }
+       }
 
-    if (find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
-        ret = pkcs11_login(pks, info, NULL);
-        if (ret < 0) {
-            gnutls_assert();
-            return ret;
-        }
+       cert_data = gnutls_malloc(MAX_CERT_SIZE);
+       if (cert_data == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
 
-        ret = find_privkeys(pks, info, &plist);
-        if (ret < 0) {
-            gnutls_assert();
-            return ret;
-        }
+       /* Find objects with cert class and X.509 cert type. */
+
+       tot_values = 0;
+
+       if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL
+           || find_data->flags ==
+           GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+               class = CKO_CERTIFICATE;
+               type = CKC_X_509;
+               trusted = 1;
+
+               a[tot_values].type = CKA_CLASS;
+               a[tot_values].value = &class;
+               a[tot_values].value_len = sizeof class;
+               tot_values++;
+
+               a[tot_values].type = CKA_CERTIFICATE_TYPE;
+               a[tot_values].value = &type;
+               a[tot_values].value_len = sizeof type;
+               tot_values++;
+
+       } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED) {
+               class = CKO_CERTIFICATE;
+               type = CKC_X_509;
+               trusted = 1;
+
+               a[tot_values].type = CKA_CLASS;
+               a[tot_values].value = &class;
+               a[tot_values].value_len = sizeof class;
+               tot_values++;
+
+               a[tot_values].type = CKA_TRUSTED;
+               a[tot_values].value = &trusted;
+               a[tot_values].value_len = sizeof trusted;
+               tot_values++;
+
+       } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY) {
+               class = CKO_PUBLIC_KEY;
+
+               a[tot_values].type = CKA_CLASS;
+               a[tot_values].value = &class;
+               a[tot_values].value_len = sizeof class;
+               tot_values++;
+       } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) {
+               class = CKO_PRIVATE_KEY;
+
+               a[tot_values].type = CKA_CLASS;
+               a[tot_values].value = &class;
+               a[tot_values].value_len = sizeof class;
+               tot_values++;
+       } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
+               if (class != -1) {
+                       a[tot_values].type = CKA_CLASS;
+                       a[tot_values].value = &class;
+                       a[tot_values].value_len = sizeof class;
+                       tot_values++;
+               }
+               if (type != -1) {
+                       a[tot_values].type = CKA_CERTIFICATE_TYPE;
+                       a[tot_values].value = &type;
+                       a[tot_values].value_len = sizeof type;
+                       tot_values++;
+               }
+       } else {
+               gnutls_assert();
+               ret = GNUTLS_E_INVALID_REQUEST;
+               goto fail;
+       }
 
-        if (plist.key_ids_size == 0) {
-            gnutls_assert();
-            return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-        }
-    } else if (find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_ALL ||
-        find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) {
-        ret = pkcs11_login(pks, info, NULL);
-        if (ret < 0) {
-            gnutls_assert();
-            return ret;
-        }
-    }
-
-    cert_data = gnutls_malloc(MAX_CERT_SIZE);
-    if (cert_data == NULL) {
-        gnutls_assert();
-        return GNUTLS_E_MEMORY_ERROR;
-    }
-
-    /* Find objects with cert class and X.509 cert type. */
-    
-    tot_values = 0;
-
-    if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL || find_data->flags==GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
-        class = CKO_CERTIFICATE;
-        type = CKC_X_509;
-        trusted = 1;
-
-        a[tot_values].type = CKA_CLASS;
-        a[tot_values].value = &class;
-        a[tot_values].value_len = sizeof class;
-        tot_values++;
-
-        a[tot_values].type = CKA_CERTIFICATE_TYPE;
-        a[tot_values].value = &type;
-        a[tot_values].value_len = sizeof type;
-        tot_values++;
-        
-    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED) {
-        class = CKO_CERTIFICATE;
-        type = CKC_X_509;
-        trusted = 1;
-
-        a[tot_values].type = CKA_CLASS;
-        a[tot_values].value = &class;
-        a[tot_values].value_len = sizeof class;
-        tot_values++;
-        
-        a[tot_values].type = CKA_TRUSTED;
-        a[tot_values].value = &trusted;
-        a[tot_values].value_len = sizeof trusted;
-        tot_values++;
-        
-    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PUBKEY) {
-        class = CKO_PUBLIC_KEY;
-
-        a[tot_values].type = CKA_CLASS;
-        a[tot_values].value = &class;
-        a[tot_values].value_len = sizeof class;
-        tot_values++;
-    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) {
-        class = CKO_PRIVATE_KEY;
-
-        a[tot_values].type = CKA_CLASS;
-        a[tot_values].value = &class;
-        a[tot_values].value_len = sizeof class;
-        tot_values++;
-    } else if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
-        if (class != -1) {
-            a[tot_values].type = CKA_CLASS;
-            a[tot_values].value = &class;
-            a[tot_values].value_len = sizeof class;
-            tot_values++;
-        }
-        if (type != -1) {
-            a[tot_values].type = CKA_CERTIFICATE_TYPE;
-            a[tot_values].value = &type;
-            a[tot_values].value_len = sizeof type;
-            tot_values++;
-        }
-    } else {
-        gnutls_assert();
-        ret = GNUTLS_E_INVALID_REQUEST;
-        goto fail;
-    }
-    
-    if (find_data->info.certid_raw_size != 0) {
-        a[tot_values].type = CKA_ID;
-        a[tot_values].value = find_data->info.certid_raw;
-        a[tot_values].value_len = find_data->info.certid_raw_size;
-        tot_values++;
-    }
-
-    rv = pakchois_find_objects_init(pks, a, tot_values);
-    if (rv != CKR_OK) {
-        gnutls_assert();
-        _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
-        return pkcs11_rv_to_err(rv);
-    }
-
-    while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
-           && count == 1) {
-        gnutls_datum_t label, id, value;
-
-        a[0].type = CKA_LABEL;
-        a[0].value = label_tmp;
-        a[0].value_len = sizeof label_tmp;
-
-        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-            label.data = a[0].value;
-            label.size = a[0].value_len;
-        } else {
-            label.data = NULL;
-            label.size = 0;
-        }
+       if (find_data->info.certid_raw_size != 0) {
+               a[tot_values].type = CKA_ID;
+               a[tot_values].value = find_data->info.certid_raw;
+               a[tot_values].value_len = find_data->info.certid_raw_size;
+               tot_values++;
+       }
 
-        a[0].type = CKA_ID;
-        a[0].value = certid_tmp;
-        a[0].value_len = sizeof certid_tmp;
-
-        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-            id.data = a[0].value;
-            id.size = a[0].value_len;
-        } else {
-            id.data = NULL;
-            id.size = 0;
-        }        
-
-        a[0].type = CKA_VALUE;
-        a[0].value = cert_data;
-        a[0].value_len = MAX_CERT_SIZE;
-        if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
-            value.data = a[0].value;
-            value.size = a[0].value_len;
-        } else {
-            value.data = NULL;
-            value.size = 0;
-        }        
-
-        if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
-            a[0].type = CKA_CLASS;
-            a[0].value = &class;
-            a[0].value_len = sizeof class;
-
-            pakchois_get_attribute_value(pks, obj, a, 1);
-        }
+       rv = pakchois_find_objects_init(pks, a, tot_values);
+       if (rv != CKR_OK) {
+               gnutls_assert();
+               _gnutls_debug_log("pk11: FindObjectsInit failed.\n");
+               return pkcs11_rv_to_err(rv);
+       }
 
-        if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
-            for (i=0;i<plist.key_ids_size;i++) {
-                if (plist.key_ids[i].length != a[1].value_len || memcmp(plist.key_ids[i].data, a[1].value, a[1].value_len)!=0) {
-                    /* not found */
-                    continue;
-                }
-            }
-        }
+       while (pakchois_find_objects(pks, &obj, 1, &count) == CKR_OK
+              && count == 1) {
+               gnutls_datum_t label, id, value;
+
+               a[0].type = CKA_LABEL;
+               a[0].value = label_tmp;
+               a[0].value_len = sizeof label_tmp;
+
+               if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+                       label.data = a[0].value;
+                       label.size = a[0].value_len;
+               } else {
+                       label.data = NULL;
+                       label.size = 0;
+               }
+
+               a[0].type = CKA_ID;
+               a[0].value = certid_tmp;
+               a[0].value_len = sizeof certid_tmp;
+
+               if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+                       id.data = a[0].value;
+                       id.size = a[0].value_len;
+               } else {
+                       id.data = NULL;
+                       id.size = 0;
+               }
+
+               a[0].type = CKA_VALUE;
+               a[0].value = cert_data;
+               a[0].value_len = MAX_CERT_SIZE;
+               if (pakchois_get_attribute_value(pks, obj, a, 1) == CKR_OK) {
+                       value.data = a[0].value;
+                       value.size = a[0].value_len;
+               } else {
+                       value.data = NULL;
+                       value.size = 0;
+               }
+
+               if (find_data->flags == GNUTLS_PKCS11_OBJ_ATTR_ALL) {
+                       a[0].type = CKA_CLASS;
+                       a[0].value = &class;
+                       a[0].value_len = sizeof class;
+
+                       pakchois_get_attribute_value(pks, obj, a, 1);
+               }
+
+               if (find_data->flags ==
+                   GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY) {
+                       for (i = 0; i < plist.key_ids_size; i++) {
+                               if (plist.key_ids[i].length !=
+                                   a[1].value_len
+                                   || memcmp(plist.key_ids[i].data,
+                                             a[1].value,
+                                             a[1].value_len) != 0) {
+                                       /* not found */
+                                       continue;
+                               }
+                       }
+               }
+
+               if (find_data->current < *find_data->n_list) {
+                       ret =
+                           gnutls_pkcs11_obj_init(&find_data->
+                                                  p_list[find_data->
+                                                         current]);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto fail;
+                       }
+
+                       if (class == CKO_PUBLIC_KEY) {
+                               ret =
+                                   pkcs11_obj_import_pubkey(pks, obj,
+                                                            find_data->
+                                                            p_list
+                                                            [find_data->
+                                                             current],
+                                                            &id, &label,
+                                                            &info->tinfo);
+                       } else {
+                               ret =
+                                   pkcs11_obj_import(class,
+                                                     find_data->
+                                                     p_list[find_data->
+                                                            current],
+                                                     &value, &id, &label,
+                                                     &info->tinfo);
+                       }
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto fail;
+                       }
+               }
+
+               find_data->current++;
 
-        if (find_data->current < *find_data->n_list) {
-            ret = gnutls_pkcs11_obj_init(&find_data->p_list[find_data->current]);
-            if (ret < 0) {
-                gnutls_assert();
-                goto fail;
-            }
-
-           if (class == CKO_PUBLIC_KEY) {
-                ret = pkcs11_obj_import_pubkey(pks, obj, find_data->p_list[find_data->current], &id, &label, &info->tinfo);
-            } else {
-                ret = pkcs11_obj_import(class, find_data->p_list[find_data->current], &value, &id, &label, &info->tinfo);
-            }
-            if (ret < 0) {
-                gnutls_assert();
-                goto fail;
-            }
-        }
-                
-        find_data->current++;
-
-    }
-
-    gnutls_free(cert_data);
-    pakchois_find_objects_final(pks);
-   
-    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* continue until all tokens have been checked */
-
-fail:
-    gnutls_free(cert_data);
-    pakchois_find_objects_final(pks);
-    if (plist.key_ids != NULL) {
-        for (i=0;i<plist.key_ids_size;i++) {
-            _gnutls_buffer_clear(&plist.key_ids[i]);
-        }
-        gnutls_free( plist.key_ids);
-    }
-    for (i=0;i<find_data->current;i++) {
-        gnutls_pkcs11_obj_deinit(find_data->p_list[i]);
-    }
-    find_data->current = 0;
-
-    return ret;
+       }
+
+       gnutls_free(cert_data);
+       pakchois_find_objects_final(pks);
+
+       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;   /* continue until all tokens have been checked */
+
+      fail:
+       gnutls_free(cert_data);
+       pakchois_find_objects_final(pks);
+       if (plist.key_ids != NULL) {
+               for (i = 0; i < plist.key_ids_size; i++) {
+                       _gnutls_buffer_clear(&plist.key_ids[i]);
+               }
+               gnutls_free(plist.key_ids);
+       }
+       for (i = 0; i < find_data->current; i++) {
+               gnutls_pkcs11_obj_deinit(find_data->p_list[i]);
+       }
+       find_data->current = 0;
+
+       return ret;
 }
 
 /**
  * gnutls_pkcs11_obj_list_import_url:
- * @p_list: An uninitialized certificate list (may be NULL)
+ * @p_list: An uninitialized object list (may be NULL)
  * @n_list: initially should hold the maximum size of the list. Will contain the actual size.
- * @url: A PKCS 11 url identifying a set of certificates
- * @flags: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
+ * @url: A PKCS 11 url identifying a set of objects
+ * @attrs: Attributes of type #gnutls_pkcs11_obj_attr_t that can be used to limit output
+ * @flags: One of GNUTLS_PKCS11_OBJ_* flags
  *
- * This function will initialize and set value to a certificate list
- * specified by a PKCS 11 URL.
+ * This function will initialize and set values to an object list
+ * by using all objects identified by a PKCS 11 URL.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, unsigned int *n_list, const char* url, gnutls_pkcs11_obj_attr_t flags)
+int gnutls_pkcs11_obj_list_import_url(gnutls_pkcs11_obj_t * p_list,
+                                     unsigned int *n_list,
+                                     const char *url,
+                                     gnutls_pkcs11_obj_attr_t attrs,
+                                      unsigned int flags)
 {
-    int ret;
-    struct crt_find_data_st find_data;
-
-    /* fill in the find data structure */
-    find_data.p_list = p_list;
-    find_data.n_list = n_list;
-    find_data.flags = flags;
-    find_data.current = 0;
-
-    if (url == NULL || url[0] == 0) {
-        url = "pkcs11:";
-    }
-
-    ret = pkcs11_url_to_info(url, &find_data.info);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = _pkcs11_traverse_tokens(find_objs, &find_data, 0);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-    
-    return 0;
+       int ret;
+       struct crt_find_data_st find_data;
+
+       /* fill in the find data structure */
+       find_data.p_list = p_list;
+       find_data.n_list = n_list;
+       find_data.flags = attrs;
+       find_data.current = 0;
+
+       if (url == NULL || url[0] == 0) {
+               url = "pkcs11:";
+       }
+
+       ret = pkcs11_url_to_info(url, &find_data.info);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret = _pkcs11_traverse_tokens(find_objs, &find_data, pkcs11_obj_flags_to_int(flags));
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       return 0;
 }
 
 /**
  * gnutls_x509_crt_import_pkcs11_url:
  * @crt: A certificate of type #gnutls_x509_crt_t
  * @url: A PKCS 11 url
+ * @flags: One of GNUTLS_PKCS11_OBJ_* flags
  *
  * This function will import a PKCS 11 certificate directly from a token
  * without involving the #gnutls_pkcs11_obj_t structure. This function will
@@ -2088,35 +2287,36 @@ int gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * p_list, unsigned in
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url)
+int gnutls_x509_crt_import_pkcs11_url(gnutls_x509_crt_t crt,
+                                const char *url, unsigned int flags)
 {
-    gnutls_pkcs11_obj_t pcrt;
-    int ret;
-    
-    ret = gnutls_pkcs11_obj_init ( &pcrt);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
-
-    ret = gnutls_pkcs11_obj_import_url (pcrt, url);
-    if (ret < 0) {
-        gnutls_assert();
-        goto cleanup;
-    }
-
-    ret = gnutls_x509_crt_import(crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
-    if (ret < 0) {
-        gnutls_assert();
-        goto cleanup;
-    }
-
-    ret = 0;
-cleanup:
-
-    gnutls_pkcs11_obj_deinit(pcrt);
-    
-    return ret;
+       gnutls_pkcs11_obj_t pcrt;
+       int ret;
+
+       ret = gnutls_pkcs11_obj_init(&pcrt);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
+
+       ret = gnutls_pkcs11_obj_import_url(pcrt, url, flags);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = gnutls_x509_crt_import(crt, &pcrt->raw, GNUTLS_X509_FMT_DER);
+       if (ret < 0) {
+               gnutls_assert();
+               goto cleanup;
+       }
+
+       ret = 0;
+      cleanup:
+
+       gnutls_pkcs11_obj_deinit(pcrt);
+
+       return ret;
 }
 
 
@@ -2131,9 +2331,11 @@ cleanup:
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pkcs11_crt)
+int gnutls_x509_crt_import_pkcs11(gnutls_x509_crt_t crt,
+                                 gnutls_pkcs11_obj_t pkcs11_crt)
 {
-    return gnutls_x509_crt_import(crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER);
+       return gnutls_x509_crt_import(crt, &pkcs11_crt->raw,
+                                     GNUTLS_X509_FMT_DER);
 }
 
 /**
@@ -2141,6 +2343,7 @@ int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pk
  * @cert: A list of certificates of type #gnutls_x509_crt_t
  * @cert_max: The maximum size of the list
  * @objs: A list of PKCS 11 objects
+ * @flags: 0 for now
  *
  * This function will import a PKCS 11 certificate list to a list of 
  * #gnutls_x509_crt_t structure. These must not be initialized.
@@ -2148,58 +2351,60 @@ int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_obj_t pk
  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
  *   negative error value.
  **/
-int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * certs,
-    unsigned int cert_max, gnutls_pkcs11_obj_t * const objs,
-    unsigned int flags)
+int gnutls_x509_crt_list_import_pkcs11(gnutls_x509_crt_t * certs,
+                                      unsigned int cert_max,
+                                      gnutls_pkcs11_obj_t * const objs,
+                                      unsigned int flags)
 {
-    int i, j;
-    int ret;
-    
-    for (i=0;i<cert_max;i++) {
-        ret = gnutls_x509_crt_init(&certs[i]);
-        if (ret < 0) {
-            gnutls_assert();
-            goto cleanup;
-        }
-        
-        ret = gnutls_x509_crt_import_pkcs11( certs[i], objs[i]);
-        if (ret < 0) {
-            gnutls_assert();
-            goto cleanup;
-        }
-    }
-    
-    return 0;
-    
-cleanup:
-    for (j=0;j<i;j++) {
-        gnutls_x509_crt_deinit(certs[j]);
-    }
-    
-    return ret;
+       int i, j;
+       int ret;
+
+       for (i = 0; i < cert_max; i++) {
+               ret = gnutls_x509_crt_init(&certs[i]);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+
+               ret = gnutls_x509_crt_import_pkcs11(certs[i], objs[i]);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+       }
+
+       return 0;
+
+      cleanup:
+       for (j = 0; j < i; j++) {
+               gnutls_x509_crt_deinit(certs[j]);
+       }
+
+       return ret;
 }
 
-static int find_flags(pakchois_session_t *pks, struct token_info *info, void* input)
+static int find_flags(pakchois_session_t * pks, struct token_info *info,
+                     void *input)
 {
-    struct flags_find_data_st* find_data = input;
+       struct flags_find_data_st *find_data = input;
 
-    if (info == NULL) { /* we don't support multiple calls */
-        gnutls_assert();
-        return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
+       if (info == NULL) {     /* we don't support multiple calls */
+               gnutls_assert();
+               return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
 
-    /* do not bother reading the token if basic fields do not match
-     */
-    if (pkcs11_token_matches_info( &find_data->info, &info->tinfo) < 0) {
+       /* do not bother reading the token if basic fields do not match
+        */
+       if (pkcs11_token_matches_info(&find_data->info, &info->tinfo) < 0) {
                gnutls_assert();
                return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
        }
 
-    /* found token! */
+       /* found token! */
 
-    find_data->slot_flags = info->sinfo.flags;
+       find_data->slot_flags = info->sinfo.flags;
 
-    return 0;
+       return 0;
 }
 
 /**
@@ -2211,72 +2416,74 @@ static int find_flags(pakchois_session_t *pks, struct token_info *info, void* in
  *
  * Returns: zero on success or a negative value on error.
  **/
-int gnutls_pkcs11_token_get_flags(const charurl, unsigned int *flags)
+int gnutls_pkcs11_token_get_flags(const char *url, unsigned int *flags)
 {
-    struct flags_find_data_st find_data;
-    int ret;
+       struct flags_find_data_st find_data;
+       int ret;
 
-    ret = pkcs11_url_to_info(url, &find_data.info);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
+       ret = pkcs11_url_to_info(url, &find_data.info);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-    ret = _pkcs11_traverse_tokens(find_flags, &find_data, 0);
-    if (ret < 0) {
-        gnutls_assert();
-        return ret;
-    }
+       ret = _pkcs11_traverse_tokens(find_flags, &find_data, 0);
+       if (ret < 0) {
+               gnutls_assert();
+               return ret;
+       }
 
-    *flags = 0;
-    if (find_data.slot_flags & CKF_HW_SLOT)
-        *flags |= GNUTLS_PKCS11_TOKEN_HW;
+       *flags = 0;
+       if (find_data.slot_flags & CKF_HW_SLOT)
+               *flags |= GNUTLS_PKCS11_TOKEN_HW;
 
-    return 0;
+       return 0;
 
 }
 
 
-const char* gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_type_t type)
+const char *gnutls_pkcs11_type_get_name(gnutls_pkcs11_obj_type_t type)
 {
-    switch(type) {
-        case GNUTLS_PKCS11_OBJ_X509_CRT:
-            return "X.509 Certificate";
-        case GNUTLS_PKCS11_OBJ_PUBKEY:
-            return "Public key";
-        case GNUTLS_PKCS11_OBJ_PRIVKEY:
-            return "Private key";
-        case GNUTLS_PKCS11_OBJ_SECRET_KEY:
-            return "Secret key";
-        case GNUTLS_PKCS11_OBJ_DATA:
-            return "Data";
-        case GNUTLS_PKCS11_OBJ_UNKNOWN:
-        default:
-            return "Unknown";
-    }
+       switch (type) {
+       case GNUTLS_PKCS11_OBJ_X509_CRT:
+               return "X.509 Certificate";
+       case GNUTLS_PKCS11_OBJ_PUBKEY:
+               return "Public key";
+       case GNUTLS_PKCS11_OBJ_PRIVKEY:
+               return "Private key";
+       case GNUTLS_PKCS11_OBJ_SECRET_KEY:
+               return "Secret key";
+       case GNUTLS_PKCS11_OBJ_DATA:
+               return "Data";
+       case GNUTLS_PKCS11_OBJ_UNKNOWN:
+       default:
+               return "Unknown";
+       }
 }
 
-int pkcs11_token_matches_info( struct pkcs11_url_info* info, struct ck_token_info* tinfo)
+int pkcs11_token_matches_info(struct pkcs11_url_info *info,
+                             struct ck_token_info *tinfo)
 {
-    if (info->manufacturer[0] != 0) {
-        if (strcmp(info->manufacturer, tinfo->manufacturer_id) != 0)
-            return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-
-    if (info->token[0] != 0) {
-        if (strcmp(info->token, tinfo->label) != 0)
-            return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-
-    if (info->model[0] != 0) {
-        if (strcmp(info->model, tinfo->model) != 0)
-            return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-
-    if (info->serial[0] != 0) {
-        if (strcmp(info->serial, tinfo->serial_number) != 0)
-            return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
-    }
-
-    return 0;
+       if (info->manufacturer[0] != 0) {
+               if (strcmp(info->manufacturer, tinfo->manufacturer_id) !=
+                   0)
+                       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+
+       if (info->token[0] != 0) {
+               if (strcmp(info->token, tinfo->label) != 0)
+                       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+
+       if (info->model[0] != 0) {
+               if (strcmp(info->model, tinfo->model) != 0)
+                       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+
+       if (info->serial[0] != 0) {
+               if (strcmp(info->serial, tinfo->serial_number) != 0)
+                       return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+       }
+
+       return 0;
 }
index b93623ab1cb434211d7396e1441f66105873b815..b41f9bbff89e248ef854ebc725929714b6dcd3cc 100644 (file)
@@ -33,7 +33,7 @@
  * @token_url: A PKCS #11 URL specifying a token
  * @crt: A certificate
  * @label: A name to be used for the stored data
- * @flags: One of GNUTLS_PKCS11_OBJ_FLAG_*
+ * @flags: One of GNUTLS_PKCS11_COPY_FLAG_*
  *
  * This function will copy a certificate into a PKCS #11 token specified by
  * a URL. The certificate can be marked as trusted or not.
@@ -127,7 +127,7 @@ int gnutls_pkcs11_copy_x509_crt(const char* token_url, gnutls_x509_crt_t crt,
                a_val++;
        }
        
-       if (flags & GNUTLS_PKCS11_OBJ_FLAG_TRUSTED) {
+       if (flags & GNUTLS_PKCS11_COPY_FLAG_MARK_TRUSTED) {
                a[a_val].type = CKA_TRUSTED;
                a[a_val].value = &tval;
                a[a_val].value_len = sizeof(tval);
@@ -161,6 +161,7 @@ cleanup:
  * @key: A private key
  * @label: A name to be used for the stored data
  * @key_usage: One of GNUTLS_KEY_*
+ * @flags: One of GNUTLS_PKCS11_COPY_* flags
  *
  * This function will copy a private key into a PKCS #11 token specified by
  * a URL. 
@@ -169,7 +170,8 @@ cleanup:
  *   negative error value.
  **/
 int gnutls_pkcs11_copy_x509_privkey(const char* token_url, 
-       gnutls_x509_privkey_t key, const char* label, unsigned int key_usage)
+       gnutls_x509_privkey_t key, const char* label, unsigned int key_usage,
+       unsigned int flags)
 {
     int ret;
     pakchois_session_t *pks;
index 95ff5dc67b9d7694dc62ad044b2b507083013c66..010eac0142f4f58b703c0ff623d9ee7acf81f8ce 100644 (file)
@@ -38,8 +38,8 @@ enum
 #define TYPE_CRQ 2
 
 void certtool_version (void);
-void pkcs11_list( FILE*outfile, const char* url, int type);
-void pkcs11_export(FILE* outfile, const char *pkcs11_url);
+void pkcs11_list( FILE*outfile, const char* url, int type, unsigned int login);
+void pkcs11_export(FILE* outfile, const char *pkcs11_url, unsigned int login);
 void pkcs11_token_list(FILE* outfile);
 void pkcs11_write(FILE* outfile, const char *pkcs11_url, const char* label, int trusted);
 void pkcs11_delete(FILE* outfile, const char *pkcs11_url, int batch);
index 535ac4c9fec5b5368218bafc638a09256c1b5254..3d5bda80598b31490392472b8d869f063eb0fb57 100644 (file)
@@ -186,6 +186,7 @@ void gaa_help(void)
        __gaa_helpsingle(0, "pkcs11-list-all-certs", "", "List all certificates specified by a PKCS#11 URL");
        __gaa_helpsingle(0, "pkcs11-list-all", "", "List all objects specified by a PKCS#11 URL");
        __gaa_helpsingle(0, "pkcs11-list-tokens", "", "List all available tokens");
+       __gaa_helpsingle(0, "pkcs11-login", "", "Force login to token");
        __gaa_helpsingle(0, "pkcs11-write", "URL ", "Writes loaded certificates or private keys to a PKCS11 token.");
        __gaa_helpsingle(0, "pkcs11-write-label", "label ", "Sets a label for the write operation.");
        __gaa_helpsingle(0, "pkcs11-write-trusted", "", "Marks the certificate to be imported as trusted.");
@@ -207,12 +208,14 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 160 "certtool.gaa"
+#line 163 "certtool.gaa"
        int debug;
-#line 155 "certtool.gaa"
+#line 158 "certtool.gaa"
        int pkcs11_trusted;
-#line 152 "certtool.gaa"
+#line 155 "certtool.gaa"
        char* pkcs11_label;
+#line 152 "certtool.gaa"
+       int pkcs11_login;
 #line 144 "certtool.gaa"
        int pkcs11_type;
 #line 141 "certtool.gaa"
@@ -323,7 +326,7 @@ static int gaa_error = 0;
 #define GAA_MULTIPLE_OPTION     3
 
 #define GAA_REST                0
-#define GAA_NB_OPTION           64
+#define GAA_NB_OPTION           65
 #define GAAOPTID_version       1
 #define GAAOPTID_help  2
 #define GAAOPTID_debug 3
@@ -331,63 +334,64 @@ static int gaa_error = 0;
 #define GAAOPTID_pkcs11_write_trusted  5
 #define GAAOPTID_pkcs11_write_label    6
 #define GAAOPTID_pkcs11_write  7
-#define GAAOPTID_pkcs11_list_tokens    8
-#define GAAOPTID_pkcs11_list_all       9
-#define GAAOPTID_pkcs11_list_all_certs 10
-#define GAAOPTID_pkcs11_list_trusted   11
-#define GAAOPTID_pkcs11_list_privkeys  12
-#define GAAOPTID_pkcs11_list_certs     13
-#define GAAOPTID_pkcs11_export_url     14
-#define GAAOPTID_pkcs11_provider       15
-#define GAAOPTID_pkcs_cipher   16
-#define GAAOPTID_template      17
-#define GAAOPTID_infile        18
-#define GAAOPTID_outfile       19
-#define GAAOPTID_disable_quick_random  20
-#define GAAOPTID_sec_param     21
-#define GAAOPTID_bits  22
-#define GAAOPTID_outraw        23
-#define GAAOPTID_outder        24
-#define GAAOPTID_inraw 25
-#define GAAOPTID_inder 26
-#define GAAOPTID_export_ciphers        27
-#define GAAOPTID_hash  28
-#define GAAOPTID_dsa   29
-#define GAAOPTID_pkcs8 30
-#define GAAOPTID_to_p8 31
-#define GAAOPTID_to_p12        32
-#define GAAOPTID_v1    33
-#define GAAOPTID_fix_key       34
-#define GAAOPTID_pubkey_info   35
-#define GAAOPTID_pgp_key_info  36
-#define GAAOPTID_key_info      37
-#define GAAOPTID_smime_to_p7   38
-#define GAAOPTID_p7_info       39
-#define GAAOPTID_p12_info      40
-#define GAAOPTID_no_crq_extensions     41
-#define GAAOPTID_crq_info      42
-#define GAAOPTID_crl_info      43
-#define GAAOPTID_pgp_ring_info 44
-#define GAAOPTID_pgp_certificate_info  45
-#define GAAOPTID_certificate_info      46
-#define GAAOPTID_password      47
-#define GAAOPTID_load_ca_certificate   48
-#define GAAOPTID_load_ca_privkey       49
-#define GAAOPTID_load_certificate      50
-#define GAAOPTID_load_request  51
-#define GAAOPTID_load_pubkey   52
-#define GAAOPTID_load_privkey  53
-#define GAAOPTID_get_dh_params 54
-#define GAAOPTID_generate_dh_params    55
-#define GAAOPTID_verify_crl    56
-#define GAAOPTID_verify_chain  57
-#define GAAOPTID_generate_request      58
-#define GAAOPTID_generate_privkey      59
-#define GAAOPTID_update_certificate    60
-#define GAAOPTID_generate_crl  61
-#define GAAOPTID_generate_proxy        62
-#define GAAOPTID_generate_certificate  63
-#define GAAOPTID_generate_self_signed  64
+#define GAAOPTID_pkcs11_login  8
+#define GAAOPTID_pkcs11_list_tokens    9
+#define GAAOPTID_pkcs11_list_all       10
+#define GAAOPTID_pkcs11_list_all_certs 11
+#define GAAOPTID_pkcs11_list_trusted   12
+#define GAAOPTID_pkcs11_list_privkeys  13
+#define GAAOPTID_pkcs11_list_certs     14
+#define GAAOPTID_pkcs11_export_url     15
+#define GAAOPTID_pkcs11_provider       16
+#define GAAOPTID_pkcs_cipher   17
+#define GAAOPTID_template      18
+#define GAAOPTID_infile        19
+#define GAAOPTID_outfile       20
+#define GAAOPTID_disable_quick_random  21
+#define GAAOPTID_sec_param     22
+#define GAAOPTID_bits  23
+#define GAAOPTID_outraw        24
+#define GAAOPTID_outder        25
+#define GAAOPTID_inraw 26
+#define GAAOPTID_inder 27
+#define GAAOPTID_export_ciphers        28
+#define GAAOPTID_hash  29
+#define GAAOPTID_dsa   30
+#define GAAOPTID_pkcs8 31
+#define GAAOPTID_to_p8 32
+#define GAAOPTID_to_p12        33
+#define GAAOPTID_v1    34
+#define GAAOPTID_fix_key       35
+#define GAAOPTID_pubkey_info   36
+#define GAAOPTID_pgp_key_info  37
+#define GAAOPTID_key_info      38
+#define GAAOPTID_smime_to_p7   39
+#define GAAOPTID_p7_info       40
+#define GAAOPTID_p12_info      41
+#define GAAOPTID_no_crq_extensions     42
+#define GAAOPTID_crq_info      43
+#define GAAOPTID_crl_info      44
+#define GAAOPTID_pgp_ring_info 45
+#define GAAOPTID_pgp_certificate_info  46
+#define GAAOPTID_certificate_info      47
+#define GAAOPTID_password      48
+#define GAAOPTID_load_ca_certificate   49
+#define GAAOPTID_load_ca_privkey       50
+#define GAAOPTID_load_certificate      51
+#define GAAOPTID_load_request  52
+#define GAAOPTID_load_pubkey   53
+#define GAAOPTID_load_privkey  54
+#define GAAOPTID_get_dh_params 55
+#define GAAOPTID_generate_dh_params    56
+#define GAAOPTID_verify_crl    57
+#define GAAOPTID_verify_chain  58
+#define GAAOPTID_generate_request      59
+#define GAAOPTID_generate_privkey      60
+#define GAAOPTID_update_certificate    61
+#define GAAOPTID_generate_crl  62
+#define GAAOPTID_generate_proxy        63
+#define GAAOPTID_generate_certificate  64
+#define GAAOPTID_generate_self_signed  65
 
 #line 168 "gaa.skel"
 
@@ -748,6 +752,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECK1STR("v", GAAOPTID_version);
                        GAA_CHECK1STR("h", GAAOPTID_help);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_write_trusted);
+                       GAA_CHECK1STR("", GAAOPTID_pkcs11_login);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_tokens);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_all);
                        GAA_CHECK1STR("", GAAOPTID_pkcs11_list_all_certs);
@@ -800,6 +805,7 @@ static int gaa_get_option_num(char *str, int status)
                        GAA_CHECKSTR("pkcs11-write-trusted", GAAOPTID_pkcs11_write_trusted);
                        GAA_CHECKSTR("pkcs11-write-label", GAAOPTID_pkcs11_write_label);
                        GAA_CHECKSTR("pkcs11-write", GAAOPTID_pkcs11_write);
+                       GAA_CHECKSTR("pkcs11-login", GAAOPTID_pkcs11_login);
                        GAA_CHECKSTR("pkcs11-list-tokens", GAAOPTID_pkcs11_list_tokens);
                        GAA_CHECKSTR("pkcs11-list-all", GAAOPTID_pkcs11_list_all);
                        GAA_CHECKSTR("pkcs11-list-all-certs", GAAOPTID_pkcs11_list_all_certs);
@@ -911,14 +917,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
     {
        case GAAOPTID_version:
        OK = 0;
-#line 165 "certtool.gaa"
+#line 168 "certtool.gaa"
 { certtool_version(); exit(0); ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_help:
        OK = 0;
-#line 163 "certtool.gaa"
+#line 166 "certtool.gaa"
 { gaa_help(); exit(0); ;};
 
                return GAA_OK;
@@ -928,7 +934,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1);
                gaa_index++;
-#line 161 "certtool.gaa"
+#line 164 "certtool.gaa"
 { gaaval->debug = GAATMP_debug.arg1 ;};
 
                return GAA_OK;
@@ -938,14 +944,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs11_delete_url.arg1, gaa_getstr, GAATMP_pkcs11_delete_url.size1);
                gaa_index++;
-#line 158 "certtool.gaa"
+#line 161 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_DELETE_URL; gaaval->pkcs11_url = GAATMP_pkcs11_delete_url.arg1; ;};
 
                return GAA_OK;
                break;
        case GAAOPTID_pkcs11_write_trusted:
        OK = 0;
-#line 156 "certtool.gaa"
+#line 159 "certtool.gaa"
 { gaaval->pkcs11_trusted = 1; ;};
 
                return GAA_OK;
@@ -955,7 +961,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs11_write_label.arg1, gaa_getstr, GAATMP_pkcs11_write_label.size1);
                gaa_index++;
-#line 154 "certtool.gaa"
+#line 157 "certtool.gaa"
 { gaaval->pkcs11_label = GAATMP_pkcs11_write_label.arg1; ;};
 
                return GAA_OK;
@@ -965,9 +971,16 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_pkcs11_write.arg1, gaa_getstr, GAATMP_pkcs11_write.size1);
                gaa_index++;
-#line 153 "certtool.gaa"
+#line 156 "certtool.gaa"
 { gaaval->action = ACTION_PKCS11_WRITE_URL; gaaval->pkcs11_url = GAATMP_pkcs11_write.arg1; ;};
 
+               return GAA_OK;
+               break;
+       case GAAOPTID_pkcs11_login:
+       OK = 0;
+#line 153 "certtool.gaa"
+{ gaaval->pkcs11_login = 1; ;};
+
                return GAA_OK;
                break;
        case GAAOPTID_pkcs11_list_tokens:
@@ -1441,14 +1454,14 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     if(inited == 0)
     {
 
-#line 167 "certtool.gaa"
+#line 170 "certtool.gaa"
 { gaaval->bits = 0; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL;
        gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL; 
        gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0;
        gaaval->export = 0; gaaval->template = NULL; gaaval->hash=NULL; gaaval->fix_key = 0; gaaval->quick_random=1; 
        gaaval->privkey_op = 0; gaaval->pkcs_cipher = "3des"; gaaval->crq_extensions=1; gaaval->pkcs11_provider= NULL;
        gaaval->pkcs11_url = NULL; gaaval->pkcs11_type = PKCS11_TYPE_PK; gaaval->pubkey=NULL; gaaval->pkcs11_label = NULL; 
-       gaaval->pkcs11_trusted=0; gaaval->sec_param = NULL; ;};
+       gaaval->pkcs11_trusted=0; gaaval->sec_param = NULL; gaaval->pkcs11_login = 0; ;};
 
     }
     inited = 1;
index 8e9f2ff8ffb9e6de88138014be2078d061844a1b..c64ffb3bd1de3429903316e79c6d87a043d3ca12 100644 (file)
@@ -8,12 +8,14 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 160 "certtool.gaa"
+#line 163 "certtool.gaa"
        int debug;
-#line 155 "certtool.gaa"
+#line 158 "certtool.gaa"
        int pkcs11_trusted;
-#line 152 "certtool.gaa"
+#line 155 "certtool.gaa"
        char* pkcs11_label;
+#line 152 "certtool.gaa"
+       int pkcs11_login;
 #line 144 "certtool.gaa"
        int pkcs11_type;
 #line 141 "certtool.gaa"
index 962268a5bdb2314ed556630f9f77205e2ee408d2..02a44173ce995fc7f78a33db075026b5b39191bc 100644 (file)
@@ -1127,13 +1127,13 @@ gaa_parser (int argc, char **argv)
       generate_pkcs8 ();
       break;
     case ACTION_PKCS11_LIST:
-      pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type);
+      pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type, info.pkcs11_login);
       break;
     case ACTION_PKCS11_TOKENS:
       pkcs11_token_list(outfile);
       break;
     case ACTION_PKCS11_EXPORT_URL:
-      pkcs11_export(outfile, info.pkcs11_url);
+      pkcs11_export(outfile, info.pkcs11_url, info.pkcs11_login);
       break;
     case ACTION_PKCS11_WRITE_URL:
       pkcs11_write(outfile, info.pkcs11_url, info.pkcs11_label, info.pkcs11_trusted);
index 0f7be24d4ace280137b86cc05ee0a347f6125fac..1fcdc20f2181d1597afa45a865d2172906d3f338 100644 (file)
@@ -149,6 +149,9 @@ option (pkcs11-list-all-certs) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS
 option (pkcs11-list-all) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_ALL; } "List all objects specified by a PKCS#11 URL"
 option (pkcs11-list-tokens) { $action = ACTION_PKCS11_TOKENS; } "List all available tokens"
 
+#int pkcs11_login;
+option (pkcs11-login) { $pkcs11_login = 1; } "Force login to token"
+
 #char* pkcs11_label;
 option (pkcs11-write) STR "URL" { $action = ACTION_PKCS11_WRITE_URL; $pkcs11_url = $1; } "Writes loaded certificates or private keys to a PKCS11 token."
 option (pkcs11-write-label) STR "label" { $pkcs11_label = $1; } "Sets a label for the write operation."
@@ -170,4 +173,4 @@ init { $bits = 0; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL;
        $export = 0; $template = NULL; $hash=NULL; $fix_key = 0; $quick_random=1; 
        $privkey_op = 0; $pkcs_cipher = "3des"; $crq_extensions=1; $pkcs11_provider= NULL;
        $pkcs11_url = NULL; $pkcs11_type = PKCS11_TYPE_PK; $pubkey=NULL; $pkcs11_label = NULL; 
-       $pkcs11_trusted=0; $sec_param = NULL; }
+       $pkcs11_trusted=0; $sec_param = NULL; $pkcs11_login = 0; }
index bab94c2dce37ededdb008c4cbce94618b0e506ba..34bdf7812a1a4e224a010aa8a8b50391eb2a30d8 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -187,7 +187,11 @@ load_keys (void)
          gnutls_x509_crt_init (&x509_crt[0]);
 
          ret =
-           gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile);
+           gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, 0);
+          
+          if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+           ret = gnutls_x509_crt_import_pkcs11_url (x509_crt[0], x509_certfile, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading cert file.\n");
index d092136599aa2ca42233ea871c780df8fee50e82..f4275b940a580f42329d02f7e6a17dadcd40135b 100644 (file)
@@ -48,7 +48,7 @@ void pkcs11_delete(FILE* outfile, const char* url, int batch)
 {
 int ret;
        if (!batch) {
-               pkcs11_list(outfile, url, PKCS11_TYPE_ALL);
+               pkcs11_list(outfile, url, PKCS11_TYPE_ALL, 1/*login*/);
                ret = read_yesno("Are you sure you want to delete those objects? (Y/N): ");
                if (ret == 0) {
                        exit(1);
@@ -68,14 +68,18 @@ int ret;
                                                                                                                                                 
 /* lists certificates from a token
  */
-void pkcs11_list( FILE* outfile, const char* url, int type)
+void pkcs11_list( FILE* outfile, const char* url, int type, unsigned int login)
 {
 gnutls_pkcs11_obj_t *crt_list;
 gnutls_x509_crt_t xcrt;
 unsigned int crt_list_size = 0;
 int ret;
 char* output;
-int i, flags;
+int i, attrs;
+unsigned int obj_flags = 0;
+
+       if (login)
+               obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
 
        pkcs11_common();
 
@@ -83,15 +87,15 @@ int i, flags;
                url = "pkcs11:";
 
        if (type == PKCS11_TYPE_TRUSTED) {
-               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
+               attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
        } else if (type == PKCS11_TYPE_PK) {
-               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
+               attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
        } else if (type == PKCS11_TYPE_CRT_ALL) {
-               flags = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
+               attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
        } else if (type == PKCS11_TYPE_PRIVKEY) {
-               flags = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
+               attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
        } else {
-               flags = GNUTLS_PKCS11_OBJ_ATTR_ALL;
+               attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
        }
                
        /* give some initial value to avoid asking for the pkcs11 pin twice.
@@ -103,7 +107,8 @@ int i, flags;
                exit(1);
        }
 
-       ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, flags);
+       ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, 
+               attrs, obj_flags);
        if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
                fprintf(stderr, "Error in crt_list_import (1): %s\n", gnutls_strerror(ret));
                exit(1);
@@ -121,7 +126,7 @@ int i, flags;
                        exit(1);
                }
 
-               ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, flags);
+               ret = gnutls_pkcs11_obj_list_import_url( crt_list, &crt_list_size, url, attrs, obj_flags);
                if (ret < 0) {
                        fprintf(stderr, "Error in crt_list_import: %s\n", gnutls_strerror(ret));
                        exit(1);
@@ -160,7 +165,7 @@ int i, flags;
                
                
 
-               if (flags == GNUTLS_PKCS11_OBJ_ATTR_ALL || flags == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
+               if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
                        continue;
 
                ret = gnutls_x509_crt_init(&xcrt);
@@ -195,13 +200,17 @@ int i, flags;
        return;
 }
 
-void pkcs11_export(FILE* outfile, const char* url)
+void pkcs11_export(FILE* outfile, const char* url, unsigned int login)
 {
 gnutls_pkcs11_obj_t crt;
 gnutls_x509_crt_t xcrt;
 gnutls_pubkey_t pubkey;
 int ret;
 size_t size;
+unsigned int obj_flags = 0;
+
+       if (login)
+               obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;
 
        pkcs11_common();
 
@@ -214,7 +223,7 @@ size_t size;
                exit(1);
        }
 
-       ret = gnutls_pkcs11_obj_import_url( crt, url);
+       ret = gnutls_pkcs11_obj_import_url( crt, url, obj_flags);
        if (ret < 0) {
                fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                exit(1);
@@ -382,7 +391,7 @@ unsigned int key_usage;
        xcrt = load_cert(0);
        if (xcrt != NULL) {
                if (trusted)
-                       flags |= GNUTLS_PKCS11_OBJ_FLAG_TRUSTED;
+                       flags |= GNUTLS_PKCS11_COPY_FLAG_MARK_TRUSTED;
                ret = gnutls_pkcs11_copy_x509_crt(url, xcrt, label, flags);
                if (ret < 0) {
                        fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
@@ -394,7 +403,7 @@ unsigned int key_usage;
 
        xkey = load_private_key(0);
        if (xkey != NULL) {
-               ret = gnutls_pkcs11_copy_x509_privkey(url, xkey, label, key_usage);
+               ret = gnutls_pkcs11_copy_x509_privkey(url, xkey, label, key_usage, flags);
                if (ret < 0) {
                        fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret));
                        exit(1);