]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added PIN callbacks in structures that may require PIN access to override the global...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 16 Jul 2012 18:46:24 +0000 (20:46 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 16 Jul 2012 18:46:27 +0000 (20:46 +0200)
13 files changed:
lib/abstract_int.h
lib/gnutls_int.h
lib/gnutls_privkey.c
lib/gnutls_pubkey.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/pkcs11.h
lib/libgnutls.map
lib/pkcs11.c
lib/pkcs11_int.h
lib/pkcs11_privkey.c
lib/pkcs11_secret.c
lib/pkcs11_write.c
lib/tpm.c

index ad859e55d641b1f8c97ec17b594f6babb443ef38..c01e9834f757440f5585b0ee0592f0550f583e6a 100644 (file)
 
 #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*);
 
index 77705a304f361aa521c0c2db77899ae09924c0b4..0f8f8c1b44f18ec972fa7bd00f7c082cc66a4f3f 100644 (file)
@@ -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 */
index 0b56e5c8e45d5acc2410ea526219c71756b77de4..92809b637e24901bbb8a9641234b47300ca6a2bc 100644 (file)
 #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;
+}
index fc5b1417aa3ec605334cf822d4277b69cb7093a2..4f869206b0cf1d10778fbaead8efbe4aa0fe68ae 100644 (file)
 #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;
+}
index 6dce2e78b85746c178d7d36a8f23ed1813b92ca4..da6a4595095cc1689a2c4ed202e91d2814fd5c07 100644 (file)
@@ -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);
index 729b4c461af87f32464c4bfdeb6839badc8a5035..f806e8276088d65f2c4d3038f0a6ec960c9f2579 100644 (file)
@@ -87,6 +87,9 @@ void gnutls_pkcs11_advset_pin_function (gnutls_pin_callback_t fn,
 
 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 */
@@ -286,6 +289,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);
index 4c8826f610a73f7eddabe7c6010abdb15c600c53..08d07156d700872ea3fd57676dea5a5b6ec69671 100644 (file)
@@ -820,6 +820,10 @@ 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_3_0_0;
 
 GNUTLS_PRIVATE {
index b35f8de83365546f2b08d7ce559933ebab060a4a..9eb2445c9557436b248a074f6cb8504637b4ad4d 100644 (file)
@@ -821,6 +821,26 @@ gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj)
   return 0;
 }
 
+/**
+ * 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 +904,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 +915,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 +997,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 +1034,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 +1049,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 +1097,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 +1656,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 +1671,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 +1688,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 +1760,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 +1973,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 +2032,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 +2053,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 +2072,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 +2087,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 +2152,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 +2631,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 +2879,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)
index a77e6101273471eada2fb99f1e878fa47986d5ea..331e4eb21e1e8d23e5293c463342ac76a5a22781 100644 (file)
@@ -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);
 
index 800a45bd69971110d2e8c37ea5b866d35d7e69ef..5cfb6dfd9dbe71b56793c2bc44ad2826cff68e60 100644 (file)
@@ -33,11 +33,11 @@ struct gnutls_pkcs11_privkey_st
   gnutls_pk_algorithm_t pk_algorithm;
   unsigned int flags;
   struct p11_kit_uri *info;
-  gnutls_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;
+}
index 10d39c785500b61f30666fa675cb74bc267ebda8..03092fce7ce2c800b18baf8dbd8269da8b743eee 100644 (file)
@@ -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);
 
index 3549213f9c39c03320c5471737512339f2c3fb80..5717b992d96036e4646acf18c300fc80adb354a2 100644 (file)
@@ -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)
@@ -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)
index 956c1b6b71de02483d910cfb1008deee9798305b..1bf57c95e73b6a20c24e1c35bf806ea48b99b7a6 100644 (file)
--- 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();
@@ -998,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();