#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*);
};
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;
session->security_parameters.version = version;
}
+
#endif /* GNUTLS_INT_H */
#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
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;
}
/**
* 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
*
#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;
+}
#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)
{
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)
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;
+}
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,
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);
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 */
/* 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);
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 {
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
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)
{
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 ();
}
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;
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 ();
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;
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 ();
/**
* 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.
*
* 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 ();
}
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)
{
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);
}
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;
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);
}
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;
/* 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. */
}
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;
}
}
- 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 ();
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);
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)
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
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);
#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,
/* 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);
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;
};
/**
}
-#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) \
{
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);
}
}
- FIND_OBJECT (&sinfo, obj, pkey);
+ FIND_OBJECT (&sinfo, &pkey->pin, obj, pkey);
a[0].type = CKA_KEY_TYPE;
a[0].value = &key_type;
{
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)
* 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;
}
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);
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;
+}
}
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);
}
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);
}
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);
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)
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)
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;
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();
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();
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();
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();