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_3_0_21-46-g8b61dcc


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_0_21-46-g8b61dcc
Date: Mon, 16 Jul 2012 19:15:11 +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=8b61dcc7715562707e4c0ce6406ad820c6cad127

The branch, master has been updated
       via  8b61dcc7715562707e4c0ce6406ad820c6cad127 (commit)
       via  2da26a5814e18eec724ebc17c20211d244012f8b (commit)
       via  67f1fcc9a324ec5e9a88a04440da876a78066f27 (commit)
       via  1ae2a03a631e8bb06a08496e828c5e448931146e (commit)
       via  b92c13fba98e17628e3e63de43da3bc3966da618 (commit)
       via  eacb2e35f561f2afe67c26a8939f0ad91d68c935 (commit)
       via  72cd1d2f53f2fe6b1c8b277a5e9a96097239caf9 (commit)
       via  5045e0fffbf60e86f75c0ce5346f90137a9c8fe5 (commit)
       via  7ac000fd77be831a7c7cbcb8da3dced0040393f3 (commit)
      from  da20d68ee5373a73395995357a9f4a41b485d63a (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 8b61dcc7715562707e4c0ce6406ad820c6cad127
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 21:14:39 2012 +0200

    Allow association of a PIN function with a credentials structure.
    
    This function will be used to override any globally set ones.

commit 2da26a5814e18eec724ebc17c20211d244012f8b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 21:14:17 2012 +0200

    return value fix

commit 67f1fcc9a324ec5e9a88a04440da876a78066f27
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 20:55:31 2012 +0200

    documented updates

commit 1ae2a03a631e8bb06a08496e828c5e448931146e
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 20:50:18 2012 +0200

    Removed newly added functions and added gnutls_pkcs11_get_pin_function().

commit b92c13fba98e17628e3e63de43da3bc3966da618
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 20:46:24 2012 +0200

    Added PIN callbacks in structures that may require PIN access to override 
the global callbacks.

commit eacb2e35f561f2afe67c26a8939f0ad91d68c935
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Mon Jul 16 19:51:01 2012 +0200

    PIN callback function was made more generic than PKCS #11.

commit 72cd1d2f53f2fe6b1c8b277a5e9a96097239caf9
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jul 14 13:35:14 2012 +0200

    added missing functions

commit 5045e0fffbf60e86f75c0ce5346f90137a9c8fe5
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jul 14 13:34:12 2012 +0200

    signing keys are generated by default

commit 7ac000fd77be831a7c7cbcb8da3dced0040393f3
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Jul 14 13:30:36 2012 +0200

    random uuids are marked as such

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

Summary of changes:
 NEWS                            |   10 ++-
 doc/Makefile.am                 |    9 ++-
 doc/cha-cert-auth2.texi         |    8 +-
 lib/abstract_int.h              |   50 +++++++++++
 lib/auth/cert.h                 |    1 +
 lib/gnutls_int.h                |    6 ++
 lib/gnutls_privkey.c            |   53 ++++++------
 lib/gnutls_pubkey.c             |   47 ++++++-----
 lib/gnutls_x509.c               |  171 +++++++++++----------------------------
 lib/includes/gnutls/abstract.h  |    8 ++
 lib/includes/gnutls/gnutls.h.in |   66 +++++++++++++++
 lib/includes/gnutls/pkcs11.h    |   74 ++---------------
 lib/libgnutls.map               |    8 ++-
 lib/pkcs11.c                    |  138 ++++++++++++++++---------------
 lib/pkcs11_int.h                |   18 +++--
 lib/pkcs11_privkey.c            |   42 +++++++---
 lib/pkcs11_secret.c             |    2 +-
 lib/pkcs11_write.c              |   10 +-
 lib/tpm.c                       |   23 ++++--
 src/tpmtool.c                   |    2 +-
 20 files changed, 401 insertions(+), 345 deletions(-)

diff --git a/NEWS b/NEWS
index 1058356..97cf515 100644
--- a/NEWS
+++ b/NEWS
@@ -43,14 +43,17 @@ by Alexandre Bique.
 GNUTLS_CERT_SIGNATURE_FAILURE: Added
 GNUTLS_CAMELLIA_192_CBC: Added
 gnutls_url_is_supported: Added
-gnutls_pkcs11_advset_pin_function: Added
-gnutls_pkcs11_advset_token_function: Added
+gnutls_pkcs11_obj_list_import_url2: Added
+gnutls_pkcs11_obj_set_pin_function: Added
+gnutls_pkcs11_privkey_set_pin_function: Added
+gnutls_pkcs11_get_pin_function: Added
 gnutls_privkey_import_tpm_raw: Added
 gnutls_privkey_import_pkcs11_url: Added
 gnutls_privkey_import_openpgp_raw: Added
 gnutls_privkey_import_x509_raw: Added
 gnutls_privkey_import_ext2: Added
 gnutls_privkey_import_url: Added
+gnutls_privkey_set_pin_function: Added
 gnutls_tpm_privkey_generate: Added
 gnutls_tpm_key_list_deinit: Added
 gnutls_tpm_key_list_get_url: Added
@@ -60,12 +63,13 @@ gnutls_pubkey_import_tpm_raw: Added
 gnutls_pubkey_import_tpm_url: Added
 gnutls_pubkey_import_url: Added
 gnutls_pubkey_verify_hash2: Added
+gnutls_pubkey_set_pin_function: Added
 gnutls_x509_privkey_import2: Added
 gnutls_x509_privkey_import_openssl: Added
 gnutls_load_file: Added
 gnutls_pkcs12_simple_parse: Added
 gnutls_certificate_set_x509_system_trust: Added
-gnutls_pkcs11_obj_list_import_url2: Added
+gnutls_certificate_set_pin_function: Added
 gnutls_x509_trust_list_add_system_trust: Added
 gnutls_x509_trust_list_add_trust_file: Added
 gnutls_x509_trust_list_add_trust_mem: Added
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 98c5692..b300557 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -478,6 +478,7 @@ ENUMS += enums/gnutls_x509_subject_alt_name_t
 FUNCS =
 FUNCS += functions/gnutls_pubkey_init
 FUNCS += functions/gnutls_pubkey_deinit
+FUNCS += functions/gnutls_pubkey_set_pin_function
 FUNCS += functions/gnutls_pubkey_get_pk_algorithm
 FUNCS += functions/gnutls_pubkey_import_x509
 FUNCS += functions/gnutls_pubkey_import_pkcs11
@@ -510,6 +511,7 @@ FUNCS += functions/gnutls_pubkey_get_verify_algorithm
 FUNCS += functions/gnutls_pubkey_verify_data2
 FUNCS += functions/gnutls_privkey_init
 FUNCS += functions/gnutls_privkey_deinit
+FUNCS += functions/gnutls_privkey_set_pin_function
 FUNCS += functions/gnutls_privkey_get_pk_algorithm
 FUNCS += functions/gnutls_privkey_get_type
 FUNCS += functions/gnutls_privkey_import_pkcs11
@@ -840,6 +842,8 @@ FUNCS += functions/gnutls_verify_stored_pubkey
 FUNCS += functions/gnutls_store_commitment
 FUNCS += functions/gnutls_store_pubkey
 FUNCS += functions/gnutls_load_file
+FUNCS += functions/gnutls_url_is_supported
+FUNCS += functions/gnutls_certificate_set_pin_function
 FUNCS += functions/gnutls_ocsp_req_init
 FUNCS += functions/gnutls_ocsp_req_deinit
 FUNCS += functions/gnutls_ocsp_req_import
@@ -946,10 +950,10 @@ FUNCS += functions/gnutls_pkcs11_reinit
 FUNCS += functions/gnutls_pkcs11_deinit
 FUNCS += functions/gnutls_pkcs11_set_token_function
 FUNCS += functions/gnutls_pkcs11_set_pin_function
-FUNCS += functions/gnutls_pkcs11_advset_token_function
-FUNCS += functions/gnutls_pkcs11_advset_pin_function
+FUNCS += functions/gnutls_pkcs11_get_pin_function
 FUNCS += functions/gnutls_pkcs11_add_provider
 FUNCS += functions/gnutls_pkcs11_obj_init
+FUNCS += functions/gnutls_pkcs11_obj_set_pin_function
 FUNCS += functions/gnutls_pkcs11_obj_import_url
 FUNCS += functions/gnutls_pkcs11_obj_export_url
 FUNCS += functions/gnutls_pkcs11_obj_deinit
@@ -973,6 +977,7 @@ FUNCS += functions/gnutls_pkcs11_obj_get_type
 FUNCS += functions/gnutls_pkcs11_type_get_name
 FUNCS += functions/gnutls_x509_crt_list_import_pkcs11
 FUNCS += functions/gnutls_pkcs11_privkey_init
+FUNCS += functions/gnutls_pkcs11_privkey_set_pin_function
 FUNCS += functions/gnutls_pkcs11_privkey_deinit
 FUNCS += functions/gnutls_pkcs11_privkey_get_pk_algorithm
 FUNCS += functions/gnutls_pkcs11_privkey_get_info
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index cee6850..09acc31 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -425,16 +425,16 @@ when accessing a protected object, such as a private key, 
as well as probe
 the user to insert the token. All the initialization functions are below.
 
 @showfuncdesc{gnutls_pkcs11_init}
address@hidden,gnutls_pkcs11_set_pin_function,gnutls_pkcs11_add_provider}
address@hidden,gnutls_pkcs11_set_pin_function,gnutls_pkcs11_add_provider,gnutls_pkcs11_get_pin_function}
 
 Note that due to limitations of @acronym{PKCS} #11 there are issues when 
multiple libraries 
 are sharing a module. To avoid this problem GnuTLS uses @acronym{p11-kit}
 that provides a middleware to control access to resources over the
 multiple users.
 
-To avoid conflicts with multiple registered callbacks for PIN and token 
functions,
-the following two functions set the callbacks if they have not already been 
set.
address@hidden,gnutls_pkcs11_advset_token_function}
+To avoid conflicts with multiple registered callbacks for PIN functions,
address@hidden may be used to check for any previously
+set functions.
 
 Moreover PKCS #11 modules must be reinitialized on the child processes
 after a @funcintref{fork}. @acronym{GnuTLS} provides 
@funcref{gnutls_pkcs11_reinit}
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
index ad859e5..c01e983 100644
--- a/lib/abstract_int.h
+++ b/lib/abstract_int.h
@@ -25,6 +25,56 @@
 
 #include <gnutls/abstract.h>
 
+struct gnutls_privkey_st
+{
+  gnutls_privkey_type_t type;
+  gnutls_pk_algorithm_t pk_algorithm;
+
+  union
+  {
+    gnutls_x509_privkey_t x509;
+#ifdef ENABLE_PKCS11
+    gnutls_pkcs11_privkey_t pkcs11;
+#endif
+#ifdef ENABLE_OPENPGP
+    gnutls_openpgp_privkey_t openpgp;
+#endif
+    struct {
+      gnutls_privkey_sign_func sign_func;
+      gnutls_privkey_decrypt_func decrypt_func;
+      gnutls_privkey_deinit_func deinit_func;
+      void* userdata;
+    } ext;
+  } key;
+
+  unsigned int flags;
+  struct pin_info_st pin;
+};
+
+struct gnutls_pubkey_st
+{
+  gnutls_pk_algorithm_t pk_algorithm;
+  unsigned int bits;            /* an indication of the security parameter */
+
+  /* the size of params depends on the public
+   * key algorithm
+   * RSA: [0] is modulus
+   *      [1] is public exponent
+   * DSA: [0] is p
+   *      [1] is q
+   *      [2] is g
+   *      [3] is public key
+   */
+  gnutls_pk_params_st params;
+
+  uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE];
+  int openpgp_key_id_set;
+
+  unsigned int key_usage;       /* bits from GNUTLS_KEY_* */
+  
+  struct pin_info_st pin;
+};
+
 int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key,
                                      gnutls_pk_params_st*);
 
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index fd4e5a4..a5a80c0 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -86,6 +86,7 @@ typedef struct gnutls_certificate_credentials_st
 
   gnutls_certificate_verify_function *verify_callback;
 
+  struct pin_info_st pin;
 } certificate_credentials_st;
 
 typedef struct rsa_info_st
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 77705a3..0f8f8c1 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -409,6 +409,11 @@ struct gnutls_key_st
 };
 typedef struct gnutls_key_st *gnutls_key_st;
 
+struct pin_info_st
+{
+  gnutls_pin_callback_t cb;
+  void* data;
+};
 
 struct record_state_st;
 typedef struct record_state_st record_state_st;
@@ -925,4 +930,5 @@ _gnutls_set_current_version (gnutls_session_t session,
   session->security_parameters.version = version;
 }
 
+
 #endif /* GNUTLS_INT_H */
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
index 0b56e5c..92809b6 100644
--- a/lib/gnutls_privkey.c
+++ b/lib/gnutls_privkey.c
@@ -33,31 +33,6 @@
 #include <gnutls_sig.h>
 #include <abstract_int.h>
 
-struct gnutls_privkey_st
-{
-  gnutls_privkey_type_t type;
-  gnutls_pk_algorithm_t pk_algorithm;
-
-  union
-  {
-    gnutls_x509_privkey_t x509;
-#ifdef ENABLE_PKCS11
-    gnutls_pkcs11_privkey_t pkcs11;
-#endif
-#ifdef ENABLE_OPENPGP
-    gnutls_openpgp_privkey_t openpgp;
-#endif
-    struct {
-      gnutls_privkey_sign_func sign_func;
-      gnutls_privkey_decrypt_func decrypt_func;
-      gnutls_privkey_deinit_func deinit_func;
-      void* userdata;
-    } ext;
-  } key;
-
-  unsigned int flags;
-};
-
 /**
  * gnutls_privkey_get_type:
  * @key: should contain a #gnutls_privkey_t structure
@@ -369,6 +344,9 @@ int ret;
   pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL);
   pkey->flags = flags;
 
+  if (pkey->pin.data)
+    gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb, pkey->pin.data);
+
   return 0;
 }
 
@@ -965,7 +943,7 @@ cleanup:
 
 /**
  * gnutls_privkey_import_url:
- * @key: A key of type #gnutls_pubkey_t
+ * @key: A key of type #gnutls_privkey_t
  * @url: A PKCS 11 url
  * @flags: should be zero
  *
@@ -991,3 +969,26 @@ gnutls_privkey_import_url (gnutls_privkey_t key, const 
char *url, unsigned int f
 #endif
   return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
 }
+
+/**
+ * gnutls_privkey_set_pin_function:
+ * @key: A key of type #gnutls_privkey_t
+ * @fn: the callback
+ * @userdata: data associated with the callback
+ *
+ * This function will set a callback function to be used when
+ * required to access the object. This function overrides any other
+ * global PIN functions.
+ *
+ * Note that this function must be called right after initialization
+ * to have effect.
+ *
+ * Since: 3.1.0
+ *
+ **/
+void gnutls_privkey_set_pin_function (gnutls_privkey_t key,
+                                      gnutls_pin_callback_t fn, void *userdata)
+{
+  key->pin.cb = fn;
+  key->pin.data = userdata;
+}
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index fc5b141..4f86920 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -41,27 +41,6 @@
 #define OPENPGP_KEY_PRIMARY 2
 #define OPENPGP_KEY_SUBKEY 1
 
-struct gnutls_pubkey_st
-{
-  gnutls_pk_algorithm_t pk_algorithm;
-  unsigned int bits;            /* an indication of the security parameter */
-
-  /* the size of params depends on the public
-   * key algorithm
-   * RSA: [0] is modulus
-   *      [1] is public exponent
-   * DSA: [0] is p
-   *      [1] is q
-   *      [2] is g
-   *      [3] is public key
-   */
-  gnutls_pk_params_st params;
-
-  uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE];
-  int openpgp_key_id_set;
-
-  unsigned int key_usage;       /* bits from GNUTLS_KEY_* */
-};
 
 int pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st* params)
 {
@@ -1055,6 +1034,9 @@ gnutls_pubkey_import_pkcs11_url (gnutls_pubkey_t key, 
const char *url,
       gnutls_assert ();
       return ret;
     }
+  
+  if (key->pin.cb)
+    gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb, key->pin.data);
 
   ret = gnutls_pkcs11_obj_import_url (pcrt, url, flags);
   if (ret < 0)
@@ -1871,3 +1853,26 @@ _gnutls_dsa_q_to_hash (gnutls_pk_algorithm_t algo, const 
gnutls_pk_params_st* pa
       return GNUTLS_DIG_SHA512;
     }
 }
+
+/**
+ * gnutls_pubkey_set_pin_function:
+ * @key: A key of type #gnutls_pubkey_t
+ * @fn: the callback
+ * @userdata: data associated with the callback
+ *
+ * This function will set a callback function to be used when
+ * required to access the object. This function overrides any other
+ * global PIN functions.
+ *
+ * Note that this function must be called right after initialization
+ * to have effect.
+ *
+ * Since: 3.1.0
+ *
+ **/
+void gnutls_pubkey_set_pin_function (gnutls_pubkey_t key,
+                                      gnutls_pin_callback_t fn, void *userdata)
+{
+  key->pin.cb = fn;
+  key->pin.data = userdata;
+}
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 413fc34..540b570 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -478,51 +478,6 @@ read_cert_mem (gnutls_certificate_credentials_t res, const 
void *cert,
   return ret;
 }
 
-static int
-_gnutls_x509_raw_privkey_to_privkey (gnutls_privkey_t * privkey,
-                                     const gnutls_datum_t * raw_key,
-                                     gnutls_x509_crt_fmt_t type)
-{
-  gnutls_x509_privkey_t tmpkey;
-  int ret;
-
-  ret = gnutls_x509_privkey_init (&tmpkey);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
-  ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      gnutls_x509_privkey_deinit (tmpkey);
-      return ret;
-    }
-
-  ret = gnutls_privkey_init (privkey);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      gnutls_x509_privkey_deinit (tmpkey);
-      return ret;
-    }
-
-  ret =
-    gnutls_privkey_import_x509 (*privkey, tmpkey,
-                                GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      gnutls_x509_privkey_deinit (tmpkey);
-      gnutls_privkey_deinit (*privkey);
-      return ret;
-    }
-
-  return 0;
-}
-
 /* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory.  Type
  * indicates the certificate format.  KEY can be NULL, to indicate
  * that GnuTLS doesn't know the private key.
@@ -540,7 +495,17 @@ read_key_mem (gnutls_certificate_credentials_t res,
       tmp.data = (uint8_t *) key;
       tmp.size = key_size;
 
-      ret = _gnutls_x509_raw_privkey_to_privkey (&privkey, &tmp, type);
+      ret = gnutls_privkey_init(&privkey);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
+      
+      if (res->pin.cb)
+        gnutls_privkey_set_pin_function(privkey, res->pin.cb, res->pin.data);
+
+      ret = gnutls_privkey_import_x509_raw (privkey, &tmp, type, NULL);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -566,87 +531,28 @@ read_key_mem (gnutls_certificate_credentials_t res,
   return 0;
 }
 
-#ifdef HAVE_TROUSERS
-/* Reads a private key from a token.
- */
-static int
-read_key_tpmurl (gnutls_certificate_credentials_t res, const char *url)
-{
-  int ret;
-  gnutls_privkey_t pkey = NULL;
-
-  /* allocate space for the pkey list
-   */
-
-  ret = gnutls_privkey_init (&pkey);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
 
-  ret =
-    gnutls_privkey_import_tpm_url (pkey, url, NULL, NULL, 0);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  ret = certificate_credentials_append_pkey (res, pkey);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  return 0;
-
-cleanup:
-  if (pkey)
-    gnutls_privkey_deinit (pkey);
-
-  return ret;
-}
-#endif
-
-#ifdef ENABLE_PKCS11
 /* Reads a private key from a token.
  */
 static int
 read_key_url (gnutls_certificate_credentials_t res, const char *url)
 {
   int ret;
-  gnutls_pkcs11_privkey_t key1 = NULL;
   gnutls_privkey_t pkey = NULL;
 
   /* allocate space for the pkey list
    */
-
-  ret = gnutls_pkcs11_privkey_init (&key1);
+  ret = gnutls_privkey_init (&pkey);
   if (ret < 0)
     {
       gnutls_assert ();
       return ret;
     }
 
-  ret = gnutls_pkcs11_privkey_import_url (key1, url, 0);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
-
-  ret = gnutls_privkey_init (&pkey);
-  if (ret < 0)
-    {
-      gnutls_assert ();
-      goto cleanup;
-    }
+  if (res->pin.cb)
+    gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
 
-  ret =
-    gnutls_privkey_import_pkcs11 (pkey, key1,
-                                  GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
+  ret = gnutls_privkey_import_url (pkey, url, 0);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -666,12 +572,10 @@ cleanup:
   if (pkey)
     gnutls_privkey_deinit (pkey);
 
-  if (key1)
-    gnutls_pkcs11_privkey_deinit (key1);
-
   return ret;
 }
 
+#ifdef ENABLE_PKCS11
 /* Reads a private key from a token.
  */
 static int
@@ -865,19 +769,10 @@ read_key_file (gnutls_certificate_credentials_t res,
   size_t size;
   char *data;
 
-#ifdef ENABLE_PKCS11
-  if (strncmp (keyfile, "pkcs11:", 7) == 0)
+  if (gnutls_url_is_supported(keyfile))
     {
       return read_key_url (res, keyfile);
     }
-#endif /* ENABLE_PKCS11 */
-
-#ifdef HAVE_TROUSERS
-  if (strncmp (keyfile, "tpmkey:", 7) == 0)
-    {
-      return read_key_tpmurl (res, keyfile);
-    }
-#endif /* HAVE_TROUSERS */
 
   data = read_binary_file (keyfile, &size);
 
@@ -1055,7 +950,7 @@ certificate_credentials_append_pkey 
(gnutls_certificate_credentials_t res,
  * @res: is a #gnutls_certificate_credentials_t structure.
  * @cert_list: contains a certificate list (path) for the specified private key
  * @cert_list_size: holds the size of the certificate list
- * @key: is a gnutls_x509_privkey_t key
+ * @key: is a #gnutls_x509_privkey_t key
  *
  * This function sets a certificate/private key pair in the
  * gnutls_certificate_credentials_t structure.  This function may be
@@ -1090,6 +985,9 @@ gnutls_certificate_set_x509_key 
(gnutls_certificate_credentials_t res,
       return ret;
     }
 
+  if (res->pin.cb)
+    gnutls_privkey_set_pin_function(pkey, res->pin.cb, res->pin.data);
+
   ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY);
   if (ret < 0)
     {
@@ -1155,7 +1053,7 @@ cleanup:
  * @names_size: holds the size of the names list
  * @pcert_list: contains a certificate list (path) for the specified private 
key
  * @pcert_list_size: holds the size of the certificate list
- * @key: is a gnutls_x509_privkey_t key
+ * @key: is a #gnutls_privkey_t key
  *
  * This function sets a certificate/private key pair in the
  * gnutls_certificate_credentials_t structure.  This function may be
@@ -1197,6 +1095,9 @@ gnutls_certificate_set_key 
(gnutls_certificate_credentials_t res,
         }
     }
 
+  if (res->pin.cb)
+    gnutls_privkey_set_pin_function(key, res->pin.cb, res->pin.data);
+
   ret = certificate_credentials_append_pkey (res, key);
   if (ret < 0)
     {
@@ -2075,3 +1976,25 @@ gnutls_certificate_free_crls 
(gnutls_certificate_credentials_t sc)
   /* do nothing for now */
   return;
 }
+
+/**
+ * gnutls_certificate_credentials_t:
+ * @cred: is a #gnutls_certificate_credentials_t structure.
+ * @fn: A PIN callback
+ * @userdata: Data to be passed in the callback
+ *
+ * This function will set a callback function to be used when
+ * required to access a protected object. This function overrides any other
+ * global PIN functions.
+ *
+ * Note that this function must be called right after initialization
+ * to have effect.
+ *
+ * Since: 3.1.0
+ **/
+void gnutls_certificate_set_pin_function (gnutls_certificate_credentials_t 
cred,
+                                          gnutls_pin_callback_t fn, void 
*userdata)
+{
+  cred->pin.cb = fn;
+  cred->pin.data = userdata;
+}
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 6dce2e7..da6a459 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -55,6 +55,10 @@ typedef void (*gnutls_privkey_deinit_func) (gnutls_privkey_t 
key,
 
 int gnutls_pubkey_init (gnutls_pubkey_t * key);
 void gnutls_pubkey_deinit (gnutls_pubkey_t key);
+
+void gnutls_pubkey_set_pin_function (gnutls_pubkey_t key,
+                                      gnutls_pin_callback_t fn, void 
*userdata);
+
 int gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits);
 
 int gnutls_pubkey_import_x509 (gnutls_pubkey_t key, gnutls_x509_crt_t crt,
@@ -181,6 +185,10 @@ gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
 
 int gnutls_privkey_init (gnutls_privkey_t * key);
 void gnutls_privkey_deinit (gnutls_privkey_t key);
+
+void gnutls_privkey_set_pin_function (gnutls_privkey_t key,
+                                      gnutls_pin_callback_t fn, void 
*userdata);
+
 int gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key,
                                      unsigned int *bits);
 gnutls_privkey_type_t gnutls_privkey_get_type (gnutls_privkey_t key);
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index f39813a..89f18d8 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1142,6 +1142,7 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t 
session);
                                           res, const char *certfile,
                                           const char *keyfile,
                                           gnutls_x509_crt_fmt_t type);
+
   int gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t
                                            res, const gnutls_datum_t * cert,
                                            const gnutls_datum_t * key,
@@ -1742,6 +1743,71 @@ int gnutls_load_file(const char* filename, 
gnutls_datum_t * data);
 
 int gnutls_url_is_supported (const char* url);
 
+  /* PIN callback */
+/**
+ * gnutls_pin_flag_t:
+ * @GNUTLS_PKCS11_PIN_USER: The PIN for the user.
+ * @GNUTLS_PKCS11_PIN_SO: The PIN for the security officer.
+ * @GNUTLS_PKCS11_PIN_CONTEXT_SPECIFIC: The PIN is for a specific action and 
key like signing.
+ * @GNUTLS_PKCS11_PIN_FINAL_TRY: This is the final try before blocking.
+ * @GNUTLS_PKCS11_PIN_COUNT_LOW: Few tries remain before token blocks.
+ * @GNUTLS_PKCS11_PIN_WRONG: Last given PIN was not correct.
+ *
+ * Enumeration of different PIN flags.
+ */
+typedef enum
+  {
+    GNUTLS_PKCS11_PIN_USER = (1 << 0),
+    GNUTLS_PKCS11_PIN_SO = (1 << 1),
+    GNUTLS_PKCS11_PIN_FINAL_TRY = (1 << 2),
+    GNUTLS_PKCS11_PIN_COUNT_LOW = (1 << 3),
+    GNUTLS_PKCS11_PIN_CONTEXT_SPECIFIC = (1 << 4),
+    GNUTLS_PKCS11_PIN_WRONG = (1 << 5),
+  } gnutls_pin_flag_t;
+
+/**
+ * gnutls_pin_callback_t:
+ * @userdata: user-controlled data from gnutls_pkcs11_set_pin_function().
+ * @attempt: pin-attempt counter, initially 0.
+ * @token_url: PKCS11 URL.
+ * @token_label: label of PKCS11 token.
+ * @flags: a #gnutls_pin_flag_t flag.
+ * @pin: buffer to hold PIN, of size @pin_max.
+ * @pin_max: size of @pin buffer.
+ *
+ * Callback function type for PKCS#11 PIN entry.  It is set by
+ * gnutls_pkcs11_set_pin_function().
+ *
+ * The callback should provides the PIN code to unlock the token with
+ * label @token_label, specified by the URL @token_url.
+ *
+ * The PIN code, as a NUL-terminated ASCII string, should be copied
+ * into the @pin buffer (of maximum size @pin_max), and return 0 to
+ * indicate success.  Alternatively, the callback may return a
+ * negative gnutls error code to indicate failure and cancel PIN entry
+ * (in which case, the contents of the @pin parameter are ignored).
+ *
+ * When a PIN is required, the callback will be invoked repeatedly
+ * (and indefinitely) until either the returned PIN code is correct,
+ * the callback returns failure, or the token refuses login (e.g. when
+ * the token is locked due to too many incorrect PINs!).  For the
+ * first such invocation, the @attempt counter will have value zero;
+ * it will increase by one for each subsequent attempt.
+ *
+ * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
+ *
+ * Since: 2.12.0
+ **/
+typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt,
+                                             const char *token_url,
+                                             const char *token_label,
+                                            unsigned int flags,
+                                             char *pin, size_t pin_max);
+
+  void gnutls_certificate_set_pin_function (gnutls_certificate_credentials_t,
+                                            gnutls_pin_callback_t fn, void 
*userdata);
+
+
   /* Gnutls error codes. The mapping to a TLS alert is also shown in
    * comments.
    */
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index e1dd841..f9abc11 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -57,65 +57,6 @@ typedef int (*gnutls_pkcs11_token_callback_t) (void *const 
userdata,
                                                const char *const label,
                                                unsigned retry);
 
-/**
- * gnutls_pkcs11_pin_flag_t:
- * @GNUTLS_PKCS11_PIN_USER: The PIN for the user.
- * @GNUTLS_PKCS11_PIN_SO: The PIN for the security officer.
- * @GNUTLS_PKCS11_PIN_CONTEXT_SPECIFIC: The PIN is for a specific action and 
key like signing.
- * @GNUTLS_PKCS11_PIN_FINAL_TRY: This is the final try before blocking.
- * @GNUTLS_PKCS11_PIN_COUNT_LOW: Few tries remain before token blocks.
- * @GNUTLS_PKCS11_PIN_WRONG: Last given PIN was not correct.
- *
- * Enumeration of different PIN flags.
- */
-typedef enum
-  {
-    GNUTLS_PKCS11_PIN_USER = (1 << 0),
-    GNUTLS_PKCS11_PIN_SO = (1 << 1),
-    GNUTLS_PKCS11_PIN_FINAL_TRY = (1 << 2),
-    GNUTLS_PKCS11_PIN_COUNT_LOW = (1 << 3),
-    GNUTLS_PKCS11_PIN_CONTEXT_SPECIFIC = (1 << 4),
-    GNUTLS_PKCS11_PIN_WRONG = (1 << 5),
-  } gnutls_pkcs11_pin_flag_t;
-
-/**
- * gnutls_pkcs11_pin_callback_t:
- * @userdata: user-controlled data from gnutls_pkcs11_set_pin_function().
- * @attempt: pin-attempt counter, initially 0.
- * @token_url: PKCS11 URL.
- * @token_label: label of PKCS11 token.
- * @flags: a #gnutls_pkcs11_pin_flag_t flag.
- * @pin: buffer to hold PIN, of size @pin_max.
- * @pin_max: size of @pin buffer.
- *
- * Callback function type for PKCS#11 PIN entry.  It is set by
- * gnutls_pkcs11_set_pin_function().
- *
- * The callback should provides the PIN code to unlock the token with
- * label @token_label, specified by the URL @token_url.
- *
- * The PIN code, as a NUL-terminated ASCII string, should be copied
- * into the @pin buffer (of maximum size @pin_max), and return 0 to
- * indicate success.  Alternatively, the callback may return a
- * negative gnutls error code to indicate failure and cancel PIN entry
- * (in which case, the contents of the @pin parameter are ignored).
- *
- * When a PIN is required, the callback will be invoked repeatedly
- * (and indefinitely) until either the returned PIN code is correct,
- * the callback returns failure, or the token refuses login (e.g. when
- * the token is locked due to too many incorrect PINs!).  For the
- * first such invocation, the @attempt counter will have value zero;
- * it will increase by one for each subsequent attempt.
- *
- * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code on error.
- *
- * Since: 2.12.0
- **/
-typedef int (*gnutls_pkcs11_pin_callback_t) (void *userdata, int attempt,
-                                             const char *token_url,
-                                             const char *token_label,
-                                            unsigned int flags,
-                                             char *pin, size_t pin_max);
 
 struct gnutls_pkcs11_obj_st;
 typedef struct gnutls_pkcs11_obj_st *gnutls_pkcs11_obj_t;
@@ -135,17 +76,16 @@ void gnutls_pkcs11_deinit (void);
 void gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
                                        void *userdata);
 
-void gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
+void gnutls_pkcs11_set_pin_function (gnutls_pin_callback_t fn,
                                      void *userdata);
 
-void gnutls_pkcs11_advset_token_function (gnutls_pkcs11_token_callback_t fn,
-                                       void *userdata);
-
-void gnutls_pkcs11_advset_pin_function (gnutls_pkcs11_pin_callback_t fn,
-                                     void *userdata);
+gnutls_pin_callback_t gnutls_pkcs11_get_pin_function (void **userdata);
 
 int gnutls_pkcs11_add_provider (const char *name, const char *params);
 int gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj);
+void gnutls_pkcs11_obj_set_pin_function (gnutls_pkcs11_obj_t,
+                                         gnutls_pin_callback_t fn, 
+                                         void *userdata);
 
 #define GNUTLS_PKCS11_OBJ_FLAG_LOGIN (1<<0)     /* force login in the token 
for the operation */
 #define GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED (1<<1)      /* object marked as 
trusted */
@@ -301,7 +241,7 @@ gnutls_pkcs11_token_get_mechanism (const char *url, 
unsigned int idx,
 int gnutls_pkcs11_token_set_pin (const char *token_url,
                                 const char *oldpin,
                                 const char *newpin,
-                                unsigned int flags  /*gnutls_pkcs11_pin_flag_t 
*/
+                                unsigned int flags  /*gnutls_pin_flag_t */
                                 );
 
 int gnutls_pkcs11_token_get_url (unsigned int seq,
@@ -345,6 +285,8 @@ int gnutls_x509_crt_list_import_pkcs11 (gnutls_x509_crt_t * 
certs,
 
 /* private key functions...*/
 int gnutls_pkcs11_privkey_init (gnutls_pkcs11_privkey_t * key);
+void gnutls_pkcs11_privkey_set_pin_function (gnutls_pkcs11_privkey_t,
+                                             gnutls_pin_callback_t fn, void 
*userdata);
 void gnutls_pkcs11_privkey_deinit (gnutls_pkcs11_privkey_t key);
 int gnutls_pkcs11_privkey_get_pk_algorithm (gnutls_pkcs11_privkey_t key,
                                             unsigned int *bits);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 4c8826f..2bfc2f6 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -794,8 +794,7 @@ GNUTLS_3_0_0 {
 
 GNUTLS_3_1_0 {
   global:
-        gnutls_pkcs11_advset_pin_function;
-       gnutls_pkcs11_advset_token_function;
+        gnutls_pkcs11_get_pin_function;
        gnutls_pkcs11_obj_list_import_url2;
        gnutls_x509_trust_list_add_system_trust;
        gnutls_x509_trust_list_add_trust_file;
@@ -820,6 +819,11 @@ GNUTLS_3_1_0 {
        gnutls_privkey_import_url;
        gnutls_pubkey_import_url;
        gnutls_url_is_supported;
+       gnutls_privkey_set_pin_function;
+       gnutls_pubkey_set_pin_function;
+       gnutls_pkcs11_obj_set_pin_function;
+       gnutls_pkcs11_privkey_set_pin_function;
+       gnutls_certificate_set_pin_function;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 907cfbd..a169862 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -74,7 +74,7 @@ static struct gnutls_pkcs11_provider_s 
providers[MAX_PROVIDERS];
 static unsigned int active_providers = 0;
 static unsigned int initialized_registered = 0;
 
-gnutls_pkcs11_pin_callback_t _gnutls_pin_func;
+gnutls_pin_callback_t _gnutls_pin_func;
 void *_gnutls_pin_data;
 
 gnutls_pkcs11_token_callback_t _gnutls_token_func;
@@ -641,17 +641,17 @@ gnutls_pkcs11_deinit (void)
 
 /**
  * gnutls_pkcs11_set_pin_function:
- * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
+ * @fn: The PIN callback, a gnutls_pin_callback_t() function.
  * @userdata: data to be supplied to callback
  *
  * This function will set a callback function to be used when a PIN is
  * required for PKCS 11 operations.  See
- * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
+ * gnutls_pin_callback_t() on how the callback should behave.
  *
  * Since: 2.12.0
  **/
 void
-gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
+gnutls_pkcs11_set_pin_function (gnutls_pin_callback_t fn,
                                 void *userdata)
 {
   _gnutls_pin_func = fn;
@@ -659,28 +659,25 @@ gnutls_pkcs11_set_pin_function 
(gnutls_pkcs11_pin_callback_t fn,
 }
 
 /**
- * gnutls_pkcs11_advset_pin_function:
- * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
+ * gnutls_pkcs11_get_pin_function:
  * @userdata: data to be supplied to callback
  *
- * This function will set a callback function to be used when a PIN is
- * required for PKCS 11 operations.  See
- * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
- * 
- * This function unlike gnutls_pkcs11_set_pin_function() will only
- * set the provided function if it has not previously been set. 
+ * This function will return the callback function set using
+ * gnutls_pkcs11_set_pin_function().
  *
+ * Returns: The function set or NULL otherwise.
+ * 
  * Since: 3.1.0
  **/
-void
-gnutls_pkcs11_advset_pin_function (gnutls_pkcs11_pin_callback_t fn,
-                                void *userdata)
+gnutls_pin_callback_t
+gnutls_pkcs11_get_pin_function (void **userdata)
 {
-  if (_gnutls_pin_func == NULL)
+  if (_gnutls_pin_func != NULL)
     {
-      _gnutls_pin_func = fn;
-      _gnutls_pin_data = userdata;
+      *userdata = _gnutls_pin_data;
+      return _gnutls_pin_func;
     }
+  return NULL;
 }
 
 /**
@@ -701,30 +698,6 @@ gnutls_pkcs11_set_token_function 
(gnutls_pkcs11_token_callback_t fn,
   _gnutls_token_data = userdata;
 }
 
-/**
- * gnutls_pkcs11_advset_token_function:
- * @fn: The token callback
- * @userdata: data to be supplied to callback
- *
- * This function will set a callback function to be used when a token
- * needs to be inserted to continue PKCS 11 operations.
- *
- * This function unlike gnutls_pkcs11_set_token_function() will only
- * set the provided function if it has not previously been set. 
- *
- * Since: 3.1.0
- **/
-void
-gnutls_pkcs11_advset_token_function (gnutls_pkcs11_token_callback_t fn,
-                                  void *userdata)
-{
-  if (_gnutls_token_func==NULL)
-    {
-      _gnutls_token_func = fn;
-      _gnutls_token_data = userdata;
-    }
-}
-
 int
 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
 {
@@ -822,6 +795,26 @@ gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
 }
 
 /**
+ * gnutls_pkcs11_obj_set_pin_function:
+ * @obj: The object structure
+ * @fn: the callback
+ * @userdata: data associated with the callback
+ *
+ * This function will set a callback function to be used when
+ * required to access the object. This function overrides the global
+ * set using gnutls_pkcs11_set_pin_function().
+ *
+ * Since: 3.1.0
+ *
+ **/
+void gnutls_pkcs11_obj_set_pin_function (gnutls_pkcs11_obj_t obj,
+                                         gnutls_pin_callback_t fn, void 
*userdata)
+{
+  obj->pin.cb = fn;
+  obj->pin.data = userdata;
+}
+
+/**
  * gnutls_pkcs11_obj_deinit:
  * @obj: The structure to be initialized
  *
@@ -884,6 +877,7 @@ gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
 
 int
 pkcs11_find_object (struct pkcs11_session_info* sinfo,
+                    struct pin_info_st * pin_info,
                     ck_object_handle_t * _obj,
                     struct p11_kit_uri *info, unsigned int flags)
 {
@@ -894,7 +888,7 @@ pkcs11_find_object (struct pkcs11_session_info* sinfo,
   unsigned long count;
   ck_rv_t rv;
 
-  ret = pkcs11_open_session (sinfo, info, flags & SESSION_LOGIN);
+  ret = pkcs11_open_session (sinfo, pin_info, info, flags & SESSION_LOGIN);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -976,7 +970,9 @@ pkcs11_find_slot (struct ck_function_list ** module, 
ck_slot_id_t * slot,
 }
 
 int
-pkcs11_open_session (struct pkcs11_session_info *sinfo, struct p11_kit_uri 
*info, 
+pkcs11_open_session (struct pkcs11_session_info *sinfo, 
+                     struct pin_info_st *pin_info,
+                     struct p11_kit_uri *info, 
                      unsigned int flags)
 {
   ck_rv_t rv;
@@ -1011,7 +1007,7 @@ pkcs11_open_session (struct pkcs11_session_info *sinfo, 
struct p11_kit_uri *info
 
   if (flags & SESSION_LOGIN)
     {
-      ret = pkcs11_login (sinfo, &tinfo, info, (flags & SESSION_SO) ? 1 : 0);
+      ret = pkcs11_login (sinfo, pin_info, &tinfo, info, (flags & SESSION_SO) 
? 1 : 0);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -1026,7 +1022,9 @@ pkcs11_open_session (struct pkcs11_session_info *sinfo, 
struct p11_kit_uri *info
 
 int
 _pkcs11_traverse_tokens (find_func_t find_func, void *input,
-                         struct p11_kit_uri *info, unsigned int flags)
+                         struct p11_kit_uri *info, 
+                         struct pin_info_st *pin_info,
+                         unsigned int flags)
 {
   ck_rv_t rv;
   unsigned int found = 0, x, z;
@@ -1072,7 +1070,7 @@ _pkcs11_traverse_tokens (find_func_t find_func, void 
*input,
 
           if (flags & SESSION_LOGIN)
             {
-              ret = pkcs11_login (&sinfo, &tinfo, info, (flags & SESSION_SO) ? 
1 : 0);
+              ret = pkcs11_login (&sinfo, pin_info, &tinfo, info, (flags & 
SESSION_SO) ? 1 : 0);
               if (ret < 0)
                 {
                   gnutls_assert ();
@@ -1631,12 +1629,12 @@ pkcs11_obj_flags_to_int (unsigned int flags)
 
 /**
  * gnutls_pkcs11_obj_import_url:
- * @cert: The structure to store the parsed certificate
+ * @obj: The structure to store the object
  * @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
+ * This function will "import" a PKCS 11 URL identifying an object (e.g. 
certificate)
+ * to the #gnutls_pkcs11_obj_t structure. This does not involve any
  * parsing (such as X.509 or OpenPGP) since the #gnutls_pkcs11_obj_t is
  * format agnostic. Only data are transferred.
  *
@@ -1646,16 +1644,16 @@ pkcs11_obj_flags_to_int (unsigned int flags)
  * Since: 2.12.0
  **/
 int
-gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, const char *url,
+gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t obj, 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;
+  find_data.crt = obj;
 
-  ret = pkcs11_url_to_info (url, &cert->info);
+  ret = pkcs11_url_to_info (url, &obj->info);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1663,8 +1661,8 @@ gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t cert, 
const char *url,
     }
 
   ret =
-    _pkcs11_traverse_tokens (find_obj_url, &find_data, cert->info,
-                             pkcs11_obj_flags_to_int (flags));
+    _pkcs11_traverse_tokens (find_obj_url, &find_data, obj->info,
+                             &obj->pin, pkcs11_obj_flags_to_int (flags));
 
   if (ret < 0)
     {
@@ -1735,7 +1733,7 @@ gnutls_pkcs11_token_get_url (unsigned int seq,
   tn.seq = seq;
   tn.info = p11_kit_uri_new ();
 
-  ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, 0);
+  ret = _pkcs11_traverse_tokens (find_token_num, &tn, NULL, NULL, 0);
   if (ret < 0)
     {
       p11_kit_uri_free (tn.info);
@@ -1948,8 +1946,10 @@ retrieve_pin_from_source (const char *pinfile, struct 
ck_token_info *token_info,
 }
 
 static int
-retrieve_pin_for_callback (struct ck_token_info *token_info, int attempts,
-                           ck_user_type_t user_type, struct p11_kit_pin **pin)
+retrieve_pin_from_callback (const struct pin_info_st *pin_info,
+                            struct ck_token_info *token_info, 
+                            int attempts, ck_user_type_t user_type, 
+                            struct p11_kit_pin **pin)
 {
   char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
   unsigned int flags = 0;
@@ -2005,8 +2005,12 @@ retrieve_pin_for_callback (struct ck_token_info 
*token_info, int attempts,
   if (attempts > 0)
     flags |= GNUTLS_PKCS11_PIN_WRONG;
 
-  ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, label,
-                  flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
+  if (pin_info && pin_info->cb)
+    ret = pin_info->cb (pin_info->data, attempts, (char*)token_str, label,
+                        flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
+  else
+    ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, 
label,
+                            flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
   free (token_str);
   free (label);
 
@@ -2022,8 +2026,9 @@ retrieve_pin_for_callback (struct ck_token_info 
*token_info, int attempts,
 }
 
 static int
-retrieve_pin (struct p11_kit_uri *info, struct ck_token_info *token_info,
-              int attempts, ck_user_type_t user_type, struct p11_kit_pin **pin)
+retrieve_pin (struct pin_info_st* pin_info, struct p11_kit_uri *info, 
+              struct ck_token_info *token_info, int attempts, 
+              ck_user_type_t user_type, struct p11_kit_pin **pin)
 {
   const char *pinfile;
   int ret = GNUTLS_E_PKCS11_PIN_ERROR;
@@ -2040,7 +2045,7 @@ retrieve_pin (struct p11_kit_uri *info, struct 
ck_token_info *token_info,
 
   /* The global gnutls pin callback */
   if (_gnutls_pin_func && ret < 0)
-    ret = retrieve_pin_for_callback (token_info, attempts, user_type, pin);
+    ret = retrieve_pin_from_callback (pin_info, token_info, attempts, 
user_type, pin);
 
   /* Otherwise, PIN entry is necessary for login, so fail if there's
    * no callback. */
@@ -2055,7 +2060,7 @@ retrieve_pin (struct p11_kit_uri *info, struct 
ck_token_info *token_info,
 }
 
 int
-pkcs11_login (struct pkcs11_session_info * sinfo,
+pkcs11_login (struct pkcs11_session_info * sinfo, struct pin_info_st * 
pin_info,
               const struct token_info *tokinfo, struct p11_kit_uri *info, int 
so)
 {
   struct ck_session_info session_info;
@@ -2120,7 +2125,7 @@ pkcs11_login (struct pkcs11_session_info * sinfo,
             }
         }
 
-      ret = retrieve_pin (info, &tinfo, attempt++, user_type, &pin);
+      ret = retrieve_pin (pin_info, info, &tinfo, attempt++, user_type, &pin);
       if (ret < 0)
         {
           gnutls_assert ();
@@ -2599,6 +2604,7 @@ gnutls_pkcs11_obj_list_import_url (gnutls_pkcs11_obj_t * 
p_list,
 
   ret =
     _pkcs11_traverse_tokens (find_objs, &find_data, find_data.info,
+                             NULL,
                              pkcs11_obj_flags_to_int (flags));
   p11_kit_uri_free (find_data.info);
 
@@ -2846,7 +2852,7 @@ gnutls_pkcs11_token_get_flags (const char *url, unsigned 
int *flags)
       return ret;
     }
 
-  ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, 0);
+  ret = _pkcs11_traverse_tokens (find_flags, &find_data, find_data.info, NULL, 
0);
   p11_kit_uri_free (find_data.info);
 
   if (ret < 0)
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 4da4107..331e4eb 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -34,7 +34,7 @@
 #include <p11-kit/uri.h>
 typedef unsigned char ck_bool_t;
 
-extern gnutls_pkcs11_pin_callback_t _gnutls_pin_func;
+extern gnutls_pin_callback_t _gnutls_pin_func;
 extern void *_gnutls_pin_data;
 
 struct pkcs11_session_info {
@@ -62,6 +62,8 @@ struct gnutls_pkcs11_obj_st
   gnutls_datum_t pubkey[MAX_PUBLIC_PARAMS_SIZE];
   gnutls_pk_algorithm_t pk_algorithm;
   unsigned int key_usage;
+
+  struct pin_info_st pin;
 };
 
 /* thus function is called for every token in the traverse_tokens
@@ -81,8 +83,8 @@ pkcs11_find_slot (struct ck_function_list ** module, 
ck_slot_id_t * slot,
 int pkcs11_get_info (struct p11_kit_uri *info,
                      gnutls_pkcs11_obj_info_t itype, void *output,
                      size_t * output_size);
-int pkcs11_login (struct pkcs11_session_info * sinfo,
-              const struct token_info *tokinfo, struct p11_kit_uri *info, int 
so);
+int pkcs11_login (struct pkcs11_session_info * sinfo, struct pin_info_st* 
pin_info,
+                  const struct token_info *tokinfo, struct p11_kit_uri *info, 
int so);
 
 int pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry);
 
@@ -97,9 +99,12 @@ int pkcs11_info_to_url (struct p11_kit_uri *info,
 #define SESSION_LOGIN (1<<1)
 #define SESSION_SO (1<<2)       /* security officer session */
 int pkcs11_open_session (struct pkcs11_session_info* sinfo,
+                         struct pin_info_st* pin_info,
                          struct p11_kit_uri *info, unsigned int flags);
 int _pkcs11_traverse_tokens (find_func_t find_func, void *input,
-                             struct p11_kit_uri *info, unsigned int flags);
+                             struct p11_kit_uri *info, 
+                             struct pin_info_st* pin_info,
+                             unsigned int flags);
 ck_object_class_t pkcs11_strtype_to_class (const char *type);
 
 int pkcs11_token_matches_info (struct p11_kit_uri *info,
@@ -108,8 +113,9 @@ int pkcs11_token_matches_info (struct p11_kit_uri *info,
 
 /* flags are SESSION_* */
 int pkcs11_find_object (struct pkcs11_session_info* sinfo,
-                    ck_object_handle_t * _obj,
-                    struct p11_kit_uri *info, unsigned int flags);
+                        struct pin_info_st* pin_info,
+                        ck_object_handle_t * _obj,
+                        struct p11_kit_uri *info, unsigned int flags);
 
 unsigned int pkcs11_obj_flags_to_int (unsigned int flags);
 
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index 1cc4d18..5cfb6df 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -33,11 +33,11 @@ struct gnutls_pkcs11_privkey_st
   gnutls_pk_algorithm_t pk_algorithm;
   unsigned int flags;
   struct p11_kit_uri *info;
-  gnutls_pkcs11_pin_callback_t pin_func;
-  void *pin_data;
   
   struct pkcs11_session_info sinfo;
   ck_object_handle_t obj; /* the key in the session */
+
+  struct pin_info_st pin;
 };
 
 /**
@@ -128,11 +128,11 @@ gnutls_pkcs11_privkey_get_info (gnutls_pkcs11_privkey_t 
pkey,
 }
 
 
-#define FIND_OBJECT(sinfo, obj, key) \
+#define FIND_OBJECT(sinfo, pin_info, obj, key) \
        do { \
                int retries = 0; \
                int rret; \
-               ret = pkcs11_find_object (sinfo, &obj, key->info, \
+               ret = pkcs11_find_object (sinfo, pin_info, &obj, key->info, \
                                          SESSION_LOGIN); \
                if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { \
                        if (_gnutls_token_func) \
@@ -181,7 +181,7 @@ _gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t 
key,
     {
       sinfo = &_sinfo;
       memset(sinfo, 0, sizeof(*sinfo));
-      FIND_OBJECT (sinfo, obj, key);
+      FIND_OBJECT (sinfo, &key->pin, obj, key);
     }
 
   mech.mechanism = pk_to_mech(key->pk_algorithm);
@@ -285,7 +285,7 @@ gnutls_pkcs11_privkey_import_url (gnutls_pkcs11_privkey_t 
pkey,
         }
     }
 
-  FIND_OBJECT (&sinfo, obj, pkey);
+  FIND_OBJECT (&sinfo, &pkey->pin, obj, pkey);
 
   a[0].type = CKA_KEY_TYPE;
   a[0].value = &key_type;
@@ -359,7 +359,7 @@ _gnutls_pkcs11_privkey_decrypt_data 
(gnutls_pkcs11_privkey_t key,
     {
       sinfo = &_sinfo;
       memset(sinfo, 0, sizeof(*sinfo));
-      FIND_OBJECT (sinfo, obj, key);
+      FIND_OBJECT (sinfo, &key->pin, obj, key);
     }
 
   if (key->pk_algorithm != GNUTLS_PK_RSA)
@@ -460,9 +460,9 @@ gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t 
key,
  * Since: 3.0
  **/
 int
-gnutls_pkcs11_privkey_generate (const char* url, 
-  gnutls_pk_algorithm_t pk, unsigned int bits, 
-  const char* label, unsigned int flags)
+gnutls_pkcs11_privkey_generate (const char* url, gnutls_pk_algorithm_t pk, 
+                                unsigned int bits, const char* label, 
+                                unsigned int flags)
 {
   int ret;
   const ck_bool_t tval = 1;
@@ -486,7 +486,7 @@ gnutls_pkcs11_privkey_generate (const char* url,
     }
 
   ret =
-    pkcs11_open_session (&sinfo, info,
+    pkcs11_open_session (&sinfo, NULL, info,
                          SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
   p11_kit_uri_free (info);
 
@@ -635,3 +635,23 @@ cleanup:
 
   return ret;
 }
+
+/**
+ * gnutls_pkcs11_privkey_set_pin_function:
+ * @obj: The object structure
+ * @fn: the callback
+ * @userdata: data associated with the callback
+ *
+ * This function will set a callback function to be used when
+ * required to access the object. This function overrides the global
+ * set using gnutls_pkcs11_set_pin_function().
+ *
+ * Since: 3.1.0
+ *
+ **/
+void gnutls_pkcs11_privkey_set_pin_function (gnutls_pkcs11_privkey_t key,
+                                             gnutls_pin_callback_t fn, void 
*userdata)
+{
+  key->pin.cb = fn;
+  key->pin.data = userdata;
+}
diff --git a/lib/pkcs11_secret.c b/lib/pkcs11_secret.c
index 10d39c7..03092fc 100644
--- a/lib/pkcs11_secret.c
+++ b/lib/pkcs11_secret.c
@@ -79,7 +79,7 @@ gnutls_pkcs11_copy_secret_key (const char *token_url, 
gnutls_datum_t * key,
     }
 
   ret =
-    pkcs11_open_session (&sinfo, info,
+    pkcs11_open_session (&sinfo, NULL, info,
                          SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
   p11_kit_uri_free (info);
 
diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c
index ca72c8f..5717b99 100644
--- a/lib/pkcs11_write.c
+++ b/lib/pkcs11_write.c
@@ -73,7 +73,7 @@ gnutls_pkcs11_copy_x509_crt (const char *token_url,
     }
 
   ret =
-    pkcs11_open_session (&sinfo, info,
+    pkcs11_open_session (&sinfo, NULL, info,
                          SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
   p11_kit_uri_free (info);
 
@@ -274,7 +274,7 @@ gnutls_pkcs11_copy_x509_privkey (const char *token_url,
     }
 
   ret =
-    pkcs11_open_session (&sinfo, info,
+    pkcs11_open_session (&sinfo, NULL, info,
                          SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
   p11_kit_uri_free (info);
 
@@ -678,7 +678,7 @@ gnutls_pkcs11_delete_url (const char *object_url, unsigned 
int flags)
 
   ret =
     _pkcs11_traverse_tokens (delete_obj_url, &find_data, find_data.info,
-                             SESSION_WRITE | pkcs11_obj_flags_to_int (flags));
+                             NULL, SESSION_WRITE | pkcs11_obj_flags_to_int 
(flags));
   p11_kit_uri_free (find_data.info);
 
   if (ret < 0)
@@ -755,7 +755,7 @@ gnutls_pkcs11_token_init (const char *token_url,
  * @token_url: A PKCS #11 URL specifying a token
  * @oldpin: old user's PIN
  * @newpin: new user's PIN
- * @flags: one of #gnutls_pkcs11_pin_flag_t.
+ * @flags: one of #gnutls_pin_flag_t.
  *
  * This function will modify or set a user's PIN for the given token. 
  * If it is called to set a user pin for first time the oldpin must
@@ -790,7 +790,7 @@ gnutls_pkcs11_token_set_pin (const char *token_url,
   else
     ses_flags = SESSION_WRITE | SESSION_LOGIN;
 
-  ret = pkcs11_open_session (&sinfo, info, ses_flags);
+  ret = pkcs11_open_session (&sinfo, NULL, info, ses_flags);
   p11_kit_uri_free (info);
 
   if (ret < 0)
diff --git a/lib/tpm.c b/lib/tpm.c
index 5e35072..1bf57c9 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -176,8 +176,8 @@ static const unsigned char nullpass[20];
 static const gnutls_datum_t nulldata = {(void*)nullpass, 20};
 const TSS_UUID srk_uuid = TSS_UUID_SRK;
 
-static int tpm_pin(const TSS_UUID* uuid, TSS_FLAG storage, char* pin, 
-                   unsigned int pin_size, unsigned int attempts)
+static int tpm_pin(struct pin_info_st* pin_info, const TSS_UUID* uuid, 
TSS_FLAG storage, 
+                   char* pin, unsigned int pin_size, unsigned int attempts)
 {
 unsigned int flags = 0;
 const char* label;
@@ -203,7 +203,10 @@ int ret;
   else
     label = "unknown";
 
-  ret = _gnutls_pin_func(_gnutls_pin_data, attempts, "TPM", label, flags, pin, 
pin_size);
+  if (pin_info && pin_info->cb)
+    ret = pin_info->cb(pin_info->data, attempts, "TPM", label, flags, pin, 
pin_size);
+  else
+    ret = _gnutls_pin_func(_gnutls_pin_data, attempts, "TPM", label, flags, 
pin, pin_size);
   if (ret < 0)
     {
       gnutls_assert();
@@ -330,7 +333,7 @@ int ret, ret2;
 
       if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR)
         {
-          ret2 = tpm_pin(&srk_uuid, storage, pin1, sizeof(pin1), attempts++);
+          ret2 = tpm_pin(&pkey->pin, &srk_uuid, storage, pin1, sizeof(pin1), 
attempts++);
           if (ret2 < 0)
             {
               gnutls_assert();
@@ -341,7 +344,7 @@ int ret, ret2;
 
       if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR)
         {
-          ret2 = tpm_pin(uuid, storage, pin2, sizeof(pin2), attempts++);
+          ret2 = tpm_pin(&pkey->pin, uuid, storage, pin2, sizeof(pin2), 
attempts++);
           if (ret2 < 0)
             {
               gnutls_assert();
@@ -608,7 +611,13 @@ static int randomize_uuid(TSS_UUID* uuid)
   ret = _gnutls_rnd (GNUTLS_RND_NONCE, raw_uuid, sizeof(raw_uuid));
   if (ret < 0)
     return gnutls_assert_val(ret);
-    
+   
+  /* mark it as random uuid */
+  raw_uuid[6] &= 0x0f;
+  raw_uuid[6] |= 0x40;
+  raw_uuid[8] &= 0x0f;
+  raw_uuid[8] |= 0x80;
+  
   memcpy(&uuid->ulTimeLow, raw_uuid, 4);
   memcpy(&uuid->usTimeMid, &raw_uuid[4], 2);
   memcpy(&uuid->usTimeHigh, &raw_uuid[6], 2);
@@ -992,7 +1001,7 @@ int ret;
 
       if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR)
         {
-          ret = tpm_pin(&srk_uuid, storage, pin1, sizeof(pin1), attempts++);
+          ret = tpm_pin(&pkey->pin, &srk_uuid, storage, pin1, sizeof(pin1), 
attempts++);
           if (ret < 0)
             {
               gnutls_assert();
diff --git a/src/tpmtool.c b/src/tpmtool.c
index 1a84e1c..edd219a 100644
--- a/src/tpmtool.c
+++ b/src/tpmtool.c
@@ -97,7 +97,7 @@ cmd_parser (int argc, char **argv)
 
   if (HAVE_OPT(REGISTER))
     genflags |= GNUTLS_TPM_REGISTER_KEY;
-  if (HAVE_OPT(SIGNING))
+  if (!HAVE_OPT(LEGACY))
     genflags |= GNUTLS_TPM_KEY_SIGNING;
   if (HAVE_OPT(USER))
     genflags |= GNUTLS_TPM_KEY_USER;


hooks/post-receive
-- 
GNU gnutls



reply via email to

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