From: Nikos Mavrogiannopoulos Date: Mon, 16 Jul 2012 18:46:24 +0000 (+0200) Subject: Added PIN callbacks in structures that may require PIN access to override the global... X-Git-Tag: gnutls_3_1_0pre0~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b92c13fba98e17628e3e63de43da3bc3966da618;p=thirdparty%2Fgnutls.git Added PIN callbacks in structures that may require PIN access to override the global callbacks. --- diff --git a/lib/abstract_int.h b/lib/abstract_int.h index ad859e55d6..c01e9834f7 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -25,6 +25,56 @@ #include +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/gnutls_int.h b/lib/gnutls_int.h index 77705a304f..0f8f8c1b44 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 0b56e5c8e4..92809b637e 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -33,31 +33,6 @@ #include #include -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 fc5b1417aa..4f869206b0 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/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 6dce2e78b8..da6a459509 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/pkcs11.h b/lib/includes/gnutls/pkcs11.h index 729b4c461a..f806e82760 100644 --- a/lib/includes/gnutls/pkcs11.h +++ b/lib/includes/gnutls/pkcs11.h @@ -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); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 4c8826f610..08d07156d7 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -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 { diff --git a/lib/pkcs11.c b/lib/pkcs11.c index b35f8de833..9eb2445c95 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -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) diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h index a77e610127..331e4eb21e 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -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 800a45bd69..5cfb6dfd9d 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_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 10d39c7855..03092fce7c 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 3549213f9c..5717b992d9 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) @@ -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 956c1b6b71..1bf57c95e7 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(); @@ -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();