summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2018-05-21 11:45:11 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-05-21 11:45:11 +0000
commit66665d8152d6d5a4439da6861dbc9929db70264b (patch)
treead6da0196fb9504155772bb07a493af4130768cf
parent7f75d92eb2150a1b1cfb168fcf6d2c7d5c9bfd78 (diff)
parentf10cfdeaac1f34caaef8bda02667ddaa31eecf16 (diff)
downloadgnutls-66665d8152d6d5a4439da6861dbc9929db70264b.tar.gz
Merge branch 'tmp-pkcs11-raw' into 'master'
gnutls_pkcs11_token_get_ptr, gnutls_pkcs11_obj_get_ptr: introduced See merge request gnutls/gnutls!640
-rw-r--r--doc/Makefile.am4
-rw-r--r--doc/cha-tokens.texi14
-rw-r--r--doc/manpages/Makefile.am2
-rw-r--r--lib/errors.c2
-rw-r--r--lib/includes/gnutls/gnutls.h.in1
-rw-r--r--lib/includes/gnutls/pkcs11.h11
-rw-r--r--lib/libgnutls.map2
-rw-r--r--lib/pkcs11.c216
-rw-r--r--lib/pkcs11_int.h1
-rw-r--r--symbols.last2
-rw-r--r--tests/Makefile.am11
-rw-r--r--tests/pkcs11/pkcs11-obj-raw.c188
-rw-r--r--tests/pkcs11/pkcs11-token-raw.c138
13 files changed, 576 insertions, 16 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index fdfa33e026..468fc1427a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1309,6 +1309,8 @@ FUNCS += functions/gnutls_pkcs11_obj_get_flags
FUNCS += functions/gnutls_pkcs11_obj_get_flags.short
FUNCS += functions/gnutls_pkcs11_obj_get_info
FUNCS += functions/gnutls_pkcs11_obj_get_info.short
+FUNCS += functions/gnutls_pkcs11_obj_get_ptr
+FUNCS += functions/gnutls_pkcs11_obj_get_ptr.short
FUNCS += functions/gnutls_pkcs11_obj_get_type
FUNCS += functions/gnutls_pkcs11_obj_get_type.short
FUNCS += functions/gnutls_pkcs11_obj_import_url
@@ -1363,6 +1365,8 @@ FUNCS += functions/gnutls_pkcs11_token_get_info
FUNCS += functions/gnutls_pkcs11_token_get_info.short
FUNCS += functions/gnutls_pkcs11_token_get_mechanism
FUNCS += functions/gnutls_pkcs11_token_get_mechanism.short
+FUNCS += functions/gnutls_pkcs11_token_get_ptr
+FUNCS += functions/gnutls_pkcs11_token_get_ptr.short
FUNCS += functions/gnutls_pkcs11_token_get_random
FUNCS += functions/gnutls_pkcs11_token_get_random.short
FUNCS += functions/gnutls_pkcs11_token_get_url
diff --git a/doc/cha-tokens.texi b/doc/cha-tokens.texi
index 5915965d47..d984afcc4d 100644
--- a/doc/cha-tokens.texi
+++ b/doc/cha-tokens.texi
@@ -281,6 +281,7 @@ available in @code{gnutls/pkcs11.h}.
* Accessing objects that require a PIN::
* Reading objects::
* Writing objects::
+* PKCS11 Low Level Access::
* Using a PKCS11 token with TLS::
* Verifying certificates over PKCS11::
* p11tool Invocation::
@@ -466,6 +467,19 @@ entered before accessing the object (for operations or otherwise).
@showfuncdesc{gnutls_pkcs11_delete_url}
+@node PKCS11 Low Level Access
+@subsection Low Level Access
+
+When it is needed to use PKCS#11 functionality which is not wrapped by
+GnuTLS, it is possible to extract the PKCS#11 session, object or token pointers.
+That allows an application to still access the low-level functionality,
+while at the same time take advantage of the URI addressing scheme supported
+by GnuTLS.
+
+@showfuncdesc{gnutls_pkcs11_token_get_ptr}
+@showfuncdesc{gnutls_pkcs11_obj_get_ptr}
+
+
@node Using a PKCS11 token with TLS
@subsection Using a @acronym{PKCS} #11 token with TLS
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index b9667165a0..981407e970 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -450,6 +450,7 @@ APIMANS += gnutls_pkcs11_obj_flags_get_str.3
APIMANS += gnutls_pkcs11_obj_get_exts.3
APIMANS += gnutls_pkcs11_obj_get_flags.3
APIMANS += gnutls_pkcs11_obj_get_info.3
+APIMANS += gnutls_pkcs11_obj_get_ptr.3
APIMANS += gnutls_pkcs11_obj_get_type.3
APIMANS += gnutls_pkcs11_obj_import_url.3
APIMANS += gnutls_pkcs11_obj_init.3
@@ -477,6 +478,7 @@ APIMANS += gnutls_pkcs11_token_check_mechanism.3
APIMANS += gnutls_pkcs11_token_get_flags.3
APIMANS += gnutls_pkcs11_token_get_info.3
APIMANS += gnutls_pkcs11_token_get_mechanism.3
+APIMANS += gnutls_pkcs11_token_get_ptr.3
APIMANS += gnutls_pkcs11_token_get_random.3
APIMANS += gnutls_pkcs11_token_get_url.3
APIMANS += gnutls_pkcs11_token_init.3
diff --git a/lib/errors.c b/lib/errors.c
index 1e9a64922b..c4bc8c72b9 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -231,6 +231,8 @@ static const gnutls_error_entry error_entries[] = {
GNUTLS_E_TOO_MANY_EMPTY_PACKETS),
ERROR_ENTRY(N_("Too many handshake packets have been received."),
GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS),
+ ERROR_ENTRY(N_("More than a single object matches the criteria."),
+ GNUTLS_E_TOO_MANY_MATCHES),
ERROR_ENTRY(N_("The crypto library version is too old."),
GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY),
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index fd3b07af78..dac1c505dd 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -3079,6 +3079,7 @@ void gnutls_fips140_set_mode(gnutls_fips_mode_t mode, unsigned flags);
#define GNUTLS_E_NO_COMMON_KEY_SHARE -423
#define GNUTLS_E_REAUTH_REQUEST -424
+#define GNUTLS_E_TOO_MANY_MATCHES -425
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 630fb7d014..3a442c8284 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2016-2018 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -294,6 +295,12 @@ typedef enum {
GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER
} gnutls_pkcs11_obj_info_t;
+int
+gnutls_pkcs11_obj_get_ptr(gnutls_pkcs11_obj_t obj, void **ptr,
+ void **session, void **ohandle,
+ unsigned long *slot_id,
+ unsigned int flags);
+
int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t obj,
gnutls_pkcs11_obj_info_t itype,
void *output, size_t * output_size);
@@ -356,6 +363,10 @@ gnutls_pkcs11_token_init(const char *token_url,
const char *so_pin, const char *label);
int
+gnutls_pkcs11_token_get_ptr(const char *url, void **ptr, unsigned long *slot_id,
+ unsigned int flags);
+
+int
gnutls_pkcs11_token_get_mechanism(const char *url,
unsigned int idx,
unsigned long *mechanism);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 17cd8ff2b3..bcde6c177b 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1217,6 +1217,8 @@ GNUTLS_3_6_3
gnutls_ext_raw_parse;
gnutls_x509_crt_list_import_url;
gnutls_pcert_list_import_x509_file;
+ gnutls_pkcs11_token_get_ptr;
+ gnutls_pkcs11_obj_get_ptr;
} GNUTLS_3_6_2;
GNUTLS_FIPS140_3_4 {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index b31c1a0a14..844bfebdcf 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -65,12 +65,20 @@ struct find_flags_data_st {
unsigned int trusted;
};
-struct find_url_data_st {
+struct find_single_obj_st {
gnutls_pkcs11_obj_t obj;
bool overwrite_exts; /* only valid if looking for a certificate */
};
-struct find_obj_data_st {
+struct find_obj_session_st {
+ gnutls_pkcs11_obj_t obj;
+ struct ck_function_list *ptr;
+ ck_session_handle_t pks;
+ ck_object_handle_t ohandle;
+ unsigned long slot_id;
+};
+
+struct find_multi_obj_st {
gnutls_pkcs11_obj_t *p_list;
unsigned int current;
unsigned int flags;
@@ -87,6 +95,8 @@ struct find_token_num {
struct find_token_modname {
struct p11_kit_uri *info;
char *modname;
+ void *ptr;
+ unsigned long slot_id;
};
struct find_pkey_list_st {
@@ -625,6 +635,128 @@ gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t obj,
return pkcs11_get_info(obj->info, itype, output, output_size);
}
+static int
+find_obj_session_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
+ struct ck_token_info *tinfo, struct ck_info *lib_info,
+ void *input)
+{
+ struct find_obj_session_st *find_data = input;
+ struct ck_attribute a[4];
+ ck_rv_t rv;
+ ck_object_handle_t ctx = CK_INVALID_HANDLE;
+ unsigned long count;
+ unsigned a_vals;
+ ck_certificate_type_t type;
+ ck_object_class_t class;
+ int found = 0, ret;
+
+ if (tinfo == NULL) { /* we don't support multiple calls */
+ gnutls_assert();
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ /* do not bother reading the token if basic fields do not match
+ */
+ if (!p11_kit_uri_match_token_info(find_data->obj->info, tinfo) ||
+ !p11_kit_uri_match_module_info(find_data->obj->info,
+ lib_info)) {
+ gnutls_assert();
+ return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+ }
+
+ ret = add_obj_attrs(find_data->obj->info, a, &a_vals, &class, &type);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, a,
+ a_vals);
+ if (rv != CKR_OK) {
+ gnutls_assert();
+ _gnutls_debug_log("p11: FindObjectsInit failed.\n");
+ ret = pkcs11_rv_to_err(rv);
+ goto cleanup;
+ }
+
+ if (pkcs11_find_objects(sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK &&
+ count == 1) {
+ find_data->ptr = sinfo->module;
+ find_data->pks = sinfo->pks;
+ find_data->slot_id = sinfo->sid;
+ find_data->ohandle = ctx;
+ found = 1;
+ }
+
+ if (found == 0) {
+ gnutls_assert();
+ if (count > 1)
+ ret = GNUTLS_E_TOO_MANY_MATCHES;
+ else
+ ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
+
+ } else {
+ ret = 0;
+ }
+
+ cleanup:
+ pkcs11_find_objects_final(sinfo);
+
+ return ret;
+}
+
+
+/**
+ * gnutls_pkcs11_obj_get_ptr:
+ * @obj: should contain a #gnutls_pkcs11_obj_t type
+ * @ptr: will contain the CK_FUNCTION_LIST_PTR pointer (may be %NULL)
+ * @session: will contain the CK_SESSION_HANDLE of the object
+ * @ohandle: will contain the CK_OBJECT_HANDLE of the object
+ * @slot_id: the identifier of the slot (may be %NULL)
+ * @flags: Or sequence of GNUTLS_PKCS11_OBJ_* flags
+ *
+ * Obtains the PKCS#11 session handles of an object. @session and @ohandle
+ * must be deinitialized by the caller. The returned pointers are
+ * independent of the @obj lifetime.
+ *
+ * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
+ * on error.
+ *
+ * Since: 3.6.3
+ **/
+int
+gnutls_pkcs11_obj_get_ptr(gnutls_pkcs11_obj_t obj, void **ptr,
+ void **session, void **ohandle,
+ unsigned long *slot_id,
+ unsigned int flags)
+{
+ int ret;
+ struct find_obj_session_st find_data;
+
+ PKCS11_CHECK_INIT;
+ memset(&find_data, 0, sizeof(find_data));
+
+ find_data.obj = obj;
+
+ ret =
+ _pkcs11_traverse_tokens(find_obj_session_cb, &find_data, obj->info,
+ &obj->pin,
+ SESSION_NO_CLOSE|pkcs11_obj_flags_to_int(flags));
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ if (ptr)
+ *ptr = find_data.ptr;
+
+ *ohandle = (void*)find_data.ohandle;
+ *session = (void*)find_data.pks;
+
+ if (slot_id)
+ *slot_id = find_data.slot_id;
+
+ return 0;
+}
+
int
pkcs11_get_info(struct p11_kit_uri *info,
gnutls_pkcs11_obj_info_t itype, void *output,
@@ -1515,7 +1647,8 @@ _pkcs11_traverse_tokens(find_func_t find_func, void *input,
}
if (pks != 0 && module != NULL) {
- pkcs11_close_session(&sinfo);
+ if (ret != 0 || !(flags & SESSION_NO_CLOSE))
+ pkcs11_close_session(&sinfo);
}
return ret;
@@ -2031,11 +2164,11 @@ pkcs11_import_object(ck_object_handle_t ctx, ck_object_class_t class,
}
static int
-find_obj_url_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
+find_single_obj_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
struct ck_token_info *tinfo, struct ck_info *lib_info,
void *input)
{
- struct find_url_data_st *find_data = input;
+ struct find_single_obj_st *find_data = input;
struct ck_attribute a[4];
ck_certificate_type_t type;
ck_object_class_t class;
@@ -2061,10 +2194,8 @@ find_obj_url_cb(struct ck_function_list *module, struct pkcs11_session_info *sin
}
ret = add_obj_attrs(find_data->obj->info, a, &a_vals, &class, &type);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ if (ret < 0)
+ return gnutls_assert_val(ret);
rv = pkcs11_find_objects_init(sinfo->module, sinfo->pks, a,
a_vals);
@@ -2153,7 +2284,7 @@ gnutls_pkcs11_obj_import_url(gnutls_pkcs11_obj_t obj, const char *url,
unsigned int flags)
{
int ret;
- struct find_url_data_st find_data;
+ struct find_single_obj_st find_data;
PKCS11_CHECK_INIT;
memset(&find_data, 0, sizeof(find_data));
@@ -2172,7 +2303,7 @@ gnutls_pkcs11_obj_import_url(gnutls_pkcs11_obj_t obj, const char *url,
}
ret =
- _pkcs11_traverse_tokens(find_obj_url_cb, &find_data, obj->info,
+ _pkcs11_traverse_tokens(find_single_obj_cb, &find_data, obj->info,
&obj->pin,
pkcs11_obj_flags_to_int(flags));
if (ret < 0) {
@@ -2230,6 +2361,8 @@ find_token_modname_cb(struct ck_function_list *module, struct pkcs11_session_inf
}
find_data->modname = p11_kit_config_option(module, "module");
+ find_data->ptr = module;
+ find_data->slot_id = sinfo->sid;
return 0;
}
@@ -2404,6 +2537,59 @@ gnutls_pkcs11_token_get_info(const char *url,
}
/**
+ * gnutls_pkcs11_token_get_ptr:
+ * @url: should contain a PKCS#11 URL identifying a token
+ * @ptr: will contain the CK_FUNCTION_LIST_PTR pointer
+ * @slot_id: will contain the slot_id (may be %NULL)
+ * @flags: should be zero
+ *
+ * This function will return the function pointer of the specified
+ * token by the URL. The returned pointers are valid until
+ * gnutls is deinitialized, c.f. _global_deinit().
+ *
+ * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error code
+ * on error.
+ *
+ * Since: 3.6.3
+ **/
+int
+gnutls_pkcs11_token_get_ptr(const char *url, void **ptr, unsigned long *slot_id,
+ unsigned int flags)
+{
+ struct p11_kit_uri *info = NULL;
+ int ret;
+ struct find_token_modname tn;
+
+ PKCS11_CHECK_INIT;
+
+ ret = pkcs11_url_to_info(url, &info, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ memset(&tn, 0, sizeof(tn));
+ tn.info = info;
+
+ ret = _pkcs11_traverse_tokens(find_token_modname_cb, &tn, NULL, NULL, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ if (ptr)
+ *ptr = tn.ptr;
+ if (slot_id)
+ *slot_id = tn.slot_id;
+
+ ret = 0;
+
+ cleanup:
+ p11_kit_uri_free(info);
+ return ret;
+}
+
+/**
* gnutls_pkcs11_obj_export_url:
* @obj: Holds the PKCS 11 certificate
* @detailed: non zero if a detailed URL is required
@@ -2880,10 +3066,10 @@ find_privkeys(struct pkcs11_session_info *sinfo,
#define OBJECTS_A_TIME 8*1024
static int
-find_objs_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
+find_multi_objs_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
struct ck_token_info *tinfo, struct ck_info *lib_info, void *input)
{
- struct find_obj_data_st *find_data = input;
+ struct find_multi_obj_st *find_data = input;
struct ck_attribute a[16];
struct ck_attribute *attr;
ck_object_class_t class = (ck_object_class_t) -1;
@@ -3268,7 +3454,7 @@ gnutls_pkcs11_obj_list_import_url4(gnutls_pkcs11_obj_t ** p_list,
unsigned int flags)
{
int ret;
- struct find_obj_data_st priv;
+ struct find_multi_obj_st priv;
PKCS11_CHECK_INIT_FLAGS(flags);
@@ -3292,7 +3478,7 @@ gnutls_pkcs11_obj_list_import_url4(gnutls_pkcs11_obj_t ** p_list,
}
ret =
- _pkcs11_traverse_tokens(find_objs_cb, &priv, priv.info,
+ _pkcs11_traverse_tokens(find_multi_objs_cb, &priv, priv.info,
NULL, pkcs11_obj_flags_to_int(flags));
p11_kit_uri_free(priv.info);
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 2b0b07ad2d..62831d89c2 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -173,6 +173,7 @@ _gnutls_x509_crt_import_pkcs11_url(gnutls_x509_crt_t crt,
#define SESSION_TRUSTED (1<<3) /* session on a marked as trusted (p11-kit) module */
#define SESSION_FORCE_LOGIN (1<<4) /* force login even when CFK_LOGIN_REQUIRED is not set */
#define SESSION_CONTEXT_SPECIFIC (1<<5)
+#define SESSION_NO_CLOSE (1<<6) /* don't close session on success */
int pkcs11_open_session(struct pkcs11_session_info *sinfo,
struct pin_info_st *pin_info,
diff --git a/symbols.last b/symbols.last
index a0d80e5021..6f8c6e494b 100644
--- a/symbols.last
+++ b/symbols.last
@@ -436,6 +436,7 @@ gnutls_pkcs11_obj_flags_get_str@GNUTLS_3_4
gnutls_pkcs11_obj_get_exts@GNUTLS_3_4
gnutls_pkcs11_obj_get_flags@GNUTLS_3_4
gnutls_pkcs11_obj_get_info@GNUTLS_3_4
+gnutls_pkcs11_obj_get_ptr@GNUTLS_3_6_3
gnutls_pkcs11_obj_get_type@GNUTLS_3_4
gnutls_pkcs11_obj_import_url@GNUTLS_3_4
gnutls_pkcs11_obj_init@GNUTLS_3_4
@@ -461,6 +462,7 @@ gnutls_pkcs11_token_check_mechanism@GNUTLS_3_6_0
gnutls_pkcs11_token_get_flags@GNUTLS_3_4
gnutls_pkcs11_token_get_info@GNUTLS_3_4
gnutls_pkcs11_token_get_mechanism@GNUTLS_3_4
+gnutls_pkcs11_token_get_ptr@GNUTLS_3_6_3
gnutls_pkcs11_token_get_random@GNUTLS_3_4
gnutls_pkcs11_token_get_url@GNUTLS_3_4
gnutls_pkcs11_token_init@GNUTLS_3_4
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 290387bdac..a7e57ccea1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -288,6 +288,14 @@ pkcs11_import_url_privkey_SOURCES = pkcs11/pkcs11-import-url-privkey.c
pkcs11_import_url_privkey_DEPENDENCIES = libpkcs11mock1.la libutils.la
pkcs11_import_url_privkey_LDADD = $(LDADD) $(LIBDL)
+pkcs11_token_raw_SOURCES = pkcs11/pkcs11-token-raw.c
+pkcs11_token_raw_DEPENDENCIES = libpkcs11mock1.la libutils.la
+pkcs11_token_raw_LDADD = $(LDADD) $(LIBDL)
+
+pkcs11_obj_raw_SOURCES = pkcs11/pkcs11-obj-raw.c
+pkcs11_obj_raw_DEPENDENCIES = libpkcs11mock1.la libutils.la
+pkcs11_obj_raw_LDADD = $(LDADD) $(LIBDL)
+
pkcs11_privkey_fork_SOURCES = pkcs11/pkcs11-privkey-fork.c
pkcs11_privkey_fork_DEPENDENCIES = libpkcs11mock1.la libutils.la
pkcs11_privkey_fork_LDADD = $(LDADD) $(LIBDL)
@@ -322,7 +330,8 @@ ctests += pkcs11-cert-import-url-exts pkcs11-get-exts pkcs11-get-raw-issuer-exts
pkcs11/pkcs11-privkey-pthread pkcs11/pkcs11-pin-func pkcs11/pkcs11-obj-import \
pkcs11-privkey-fork-reinit pkcs11-mechanisms pkcs11-privkey-safenet-always-auth \
pkcs11/pkcs11-rsa-pss-privkey-test pkcs11/tls-neg-pkcs11-key pkcs11/pkcs11-privkey-generate \
- pkcs11/gnutls_x509_crt_list_import_url pkcs11/gnutls_pcert_list_import_x509_file
+ pkcs11/gnutls_x509_crt_list_import_url pkcs11/gnutls_pcert_list_import_x509_file \
+ pkcs11-token-raw pkcs11-obj-raw
endif
diff --git a/tests/pkcs11/pkcs11-obj-raw.c b/tests/pkcs11/pkcs11-obj-raw.c
new file mode 100644
index 0000000000..f093928447
--- /dev/null
+++ b/tests/pkcs11/pkcs11-obj-raw.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016-2018 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/pkcs11.h>
+#ifndef CRYPTOKI_GNU
+# define CRYPTOKI_GNU
+#endif
+#include <p11-kit/pkcs11.h>
+
+#include "utils.h"
+
+/* Tests whether a gnutls_pkcs11_obj_get_ptr returns valid handles. */
+
+#if defined(HAVE___REGISTER_ATFORK)
+
+#ifdef _WIN32
+# define P11LIB "libpkcs11mock1.dll"
+#else
+# include <dlfcn.h>
+# define P11LIB "libpkcs11mock1.so"
+#endif
+
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+#define PIN "1234"
+
+static
+int pin_func(void* userdata, int attempt, const char* url, const char *label,
+ unsigned flags, char *pin, size_t pin_max)
+{
+ if (attempt == 0) {
+ strcpy(pin, PIN);
+ return 0;
+ }
+ return -1;
+}
+
+void doit(void)
+{
+ int ret;
+ const char *lib;
+ unsigned long slot_id;
+ unsigned char sig[256];
+ unsigned long len;
+ struct ck_function_list *mod;
+ struct ck_info info;
+ struct ck_token_info tinfo;
+ ck_session_handle_t session;
+ ck_object_handle_t ohandle;
+ gnutls_pkcs11_obj_t obj;
+ struct ck_mechanism mech;
+ ck_rv_t rv;
+ gnutls_datum_t data;
+
+ data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb";
+ data.size = 20;
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ lib = getenv("P11MOCKLIB1");
+ if (lib == NULL)
+ lib = P11LIB;
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_add_provider(lib, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(gnutls_pkcs11_obj_init(&obj)>=0);
+
+ gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL);
+
+ /* unknown object */
+ ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:token=unknown;object=invalid;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+ assert(ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+ ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:object=test;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+ assert(ret >= 0);
+
+ ret = gnutls_pkcs11_obj_get_ptr(obj, (void**)&mod, (void*)&session,
+ (void*)&ohandle,
+ &slot_id, GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_pkcs11_obj_deinit(obj);
+
+ rv = mod->C_GetInfo(&info);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(info.cryptoki_version.major == 0x02);
+ assert(info.cryptoki_version.minor == 0x14);
+ assert(info.flags == 0);
+ assert(info.library_version.major == 0x01);
+ assert(info.library_version.minor == 0x00);
+
+ rv = mod->C_GetTokenInfo(slot_id, &tinfo);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(tinfo.hardware_version.major == 0x01);
+ assert(tinfo.firmware_version.major == 0x01);
+
+ mech.mechanism = CKM_RSA_PKCS;
+ mech.parameter = NULL;
+ mech.parameter_len = 0;
+
+ rv = mod->C_SignInit(session, &mech, ohandle);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ len = sizeof(sig);
+ rv = mod->C_Sign(session, data.data, data.size, sig, &len);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ mod->C_CloseSession(session);
+
+ gnutls_pkcs11_deinit();
+ gnutls_global_deinit();
+}
+#else
+void doit(void)
+{
+ exit(77);
+}
+#endif
diff --git a/tests/pkcs11/pkcs11-token-raw.c b/tests/pkcs11/pkcs11-token-raw.c
new file mode 100644
index 0000000000..bbcb23eb81
--- /dev/null
+++ b/tests/pkcs11/pkcs11-token-raw.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2016-2018 Red Hat, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <gnutls/gnutls.h>
+#include <gnutls/pkcs11.h>
+#ifndef CRYPTOKI_GNU
+# define CRYPTOKI_GNU
+#endif
+#include <p11-kit/pkcs11.h>
+
+#include "utils.h"
+
+/* Tests whether a gnutls_pkcs11_token_get_ptr returns valid handles. */
+
+#if defined(HAVE___REGISTER_ATFORK)
+
+#ifdef _WIN32
+# define P11LIB "libpkcs11mock1.dll"
+#else
+# include <dlfcn.h>
+# define P11LIB "libpkcs11mock1.so"
+#endif
+
+
+static void tls_log_func(int level, const char *str)
+{
+ fprintf(stderr, "|<%d>| %s", level, str);
+}
+
+void doit(void)
+{
+ int ret;
+ const char *lib;
+ unsigned long slot_id;
+ struct ck_function_list *mod;
+ struct ck_info info;
+ struct ck_token_info tinfo;
+ ck_rv_t rv;
+
+ ret = global_init();
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ gnutls_global_set_log_function(tls_log_func);
+ if (debug)
+ gnutls_global_set_log_level(4711);
+
+ lib = getenv("P11MOCKLIB1");
+ if (lib == NULL)
+ lib = P11LIB;
+
+ ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_add_provider(lib, NULL);
+ if (ret != 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ ret = gnutls_pkcs11_token_get_ptr("pkcs11:token=invalid", (void**)&mod, &slot_id, 0);
+ assert(ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+
+ ret = gnutls_pkcs11_token_get_ptr("pkcs11:", (void**)&mod, &slot_id, 0);
+ if (ret < 0) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ rv = mod->C_GetInfo(&info);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(info.cryptoki_version.major == 0x02);
+ assert(info.cryptoki_version.minor == 0x14);
+ assert(info.flags == 0);
+ assert(info.library_version.major == 0x01);
+ assert(info.library_version.minor == 0x00);
+
+ rv = mod->C_GetTokenInfo(slot_id, &tinfo);
+ if (rv != CKR_OK) {
+ fail("%d: %s\n", ret, gnutls_strerror(ret));
+ exit(1);
+ }
+
+ assert(tinfo.session_count == 0);
+ assert(tinfo.hardware_version.major == 0x01);
+ assert(tinfo.firmware_version.major == 0x01);
+
+ if (debug)
+ printf("done\n\n\n");
+
+ gnutls_pkcs11_deinit();
+ gnutls_global_deinit();
+}
+#else
+void doit(void)
+{
+ exit(77);
+}
+#endif