gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_9_10-263-g21e200f


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_9_10-263-g21e200f
Date: Mon, 28 Jun 2010 16:23:36 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=21e200fdfe407108ff58b8a26a2f827bf0bf38d3

The branch, master has been updated
       via  21e200fdfe407108ff58b8a26a2f827bf0bf38d3 (commit)
      from  8d5ef8910cd5e80346c5aab2399c57532c1175cd (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 21e200fdfe407108ff58b8a26a2f827bf0bf38d3
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jun 28 18:07:01 2010 +0200

    Allow flags when importing objects from PKCS11 URLs. The only flag supported
    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.

-----------------------------------------------------------------------

Summary of changes:
 doc/examples/ex-cert-select-pkcs11.c |    8 +-
 lib/gnutls_pubkey.c                  |   18 +-
 lib/gnutls_x509.c                    |   10 +-
 lib/includes/gnutls/abstract.h       |    3 +-
 lib/includes/gnutls/pkcs11.h         |   23 +-
 lib/pkcs11.c                         | 3629 ++++++++++++++++++----------------
 lib/pkcs11_write.c                   |    8 +-
 src/certtool-common.h                |    4 +-
 src/certtool-gaa.c                   |  153 +-
 src/certtool-gaa.h                   |    8 +-
 src/certtool.c                       |    4 +-
 src/certtool.gaa                     |    5 +-
 src/cli.c                            |    6 +-
 src/pkcs11.c                         |   39 +-
 14 files changed, 2096 insertions(+), 1822 deletions(-)

diff --git a/doc/examples/ex-cert-select-pkcs11.c 
b/doc/examples/ex-cert-select-pkcs11.c
index 741afd3..8ff4d2e 100644
--- a/doc/examples/ex-cert-select-pkcs11.c
+++ b/doc/examples/ex-cert-select-pkcs11.c
@@ -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",
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index 58f93b1..46d8469 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -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;
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 5d44359..996c487 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -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();
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 77e7994..6eed91d 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -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,
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 80e4b42..e7ae57a 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -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...*/
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index ebe4846..ed70073 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -37,26 +37,26 @@
 #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 void* pin_data;
+static void *pin_data;
 
 gnutls_pkcs11_token_callback_t token_func;
-void* token_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 char* configfile)
+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       "\\/\"'%&address@hidden <>{}[]()`|:;,.+-"
 
-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 char* pkcs11_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 char* type)
+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 char* url, 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;
 }
diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c
index b93623a..b41f9bb 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -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;
diff --git a/src/certtool-common.h b/src/certtool-common.h
index 95ff5dc..010eac0 100644
--- a/src/certtool-common.h
+++ b/src/certtool-common.h
@@ -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);
diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c
index 535ac4c..3d5bda8 100644
--- a/src/certtool-gaa.c
+++ b/src/certtool-gaa.c
@@ -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,11 +971,18 @@ 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:
        OK = 0;
 #line 150 "certtool.gaa"
@@ -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;
diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h
index 8e9f2ff..c64ffb3 100644
--- a/src/certtool-gaa.h
+++ b/src/certtool-gaa.h
@@ -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"
diff --git a/src/certtool.c b/src/certtool.c
index 962268a..02a4417 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -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);
diff --git a/src/certtool.gaa b/src/certtool.gaa
index 0f7be24..1fcdc20 100644
--- a/src/certtool.gaa
+++ b/src/certtool.gaa
@@ -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; }
diff --git a/src/cli.c b/src/cli.c
index bab94c2..34bdf78 100644
--- 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");
diff --git a/src/pkcs11.c b/src/pkcs11.c
index d092136..f4275b9 100644
--- a/src/pkcs11.c
+++ b/src/pkcs11.c
@@ -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);


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]