summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2010-12-31 08:06:31 -0600
committerStef Walter <stef@memberwebs.com>2011-01-19 12:40:33 -0600
commit877f01db2b7d74acfdbd4fe373d7cd37d9f6104e (patch)
tree4fc92bbc275b0bd002e8346398418189b7ae7a0a
parent4fdced65884387b7e6db9314659d30b558822a26 (diff)
downloadgcr-877f01db2b7d74acfdbd4fe373d7cd37d9f6104e.tar.gz
[gck] Update PKCS#11 URI to add library support.
Add library-description and library-description and library-manufacturer parts. And refactor to support parsing in different contexts better.
-rw-r--r--docs/reference/gck/gck-docs.sgml1
-rw-r--r--docs/reference/gck/gck-sections.txt9
-rw-r--r--gck/gck-enumerator.c49
-rw-r--r--gck/gck-misc.c39
-rw-r--r--gck/gck-modules.c63
-rw-r--r--gck/gck-private.h12
-rw-r--r--gck/gck-slot.c36
-rw-r--r--gck/gck-uri.c217
-rw-r--r--gck/gck.h29
-rw-r--r--gck/tests/gck-test.h19
-rw-r--r--gck/tests/test-gck-enumerator.c47
-rw-r--r--gck/tests/test-gck-uri.c405
-rw-r--r--gck/tests/test-gck.h43
13 files changed, 738 insertions, 231 deletions
diff --git a/docs/reference/gck/gck-docs.sgml b/docs/reference/gck/gck-docs.sgml
index 2846192..5b5e114 100644
--- a/docs/reference/gck/gck-docs.sgml
+++ b/docs/reference/gck/gck-docs.sgml
@@ -20,6 +20,7 @@
<xi:include href="xml/gck-attribute.xml"/>
<xi:include href="xml/gck-attributes.xml"/>
<xi:include href="xml/gck-error.xml"/>
+ <xi:include href="xml/gck-uri.xml"/>
<xi:include href="xml/gck-misc.xml"/>
</chapter>
</book>
diff --git a/docs/reference/gck/gck-sections.txt b/docs/reference/gck/gck-sections.txt
index d567b8e..4edad3f 100644
--- a/docs/reference/gck/gck-sections.txt
+++ b/docs/reference/gck/gck-sections.txt
@@ -189,6 +189,15 @@ CKR_GCK_MODULE_PROBLEM
</SECTION>
<SECTION>
+<FILE>gck-uri</FILE>
+GckUriInfo
+GckUriParseFlags
+gck_uri_parse
+gck_uri_build
+gck_uri_info_free
+</SECTION>
+
+<SECTION>
<FILE>gck-misc</FILE>
gck_list_ref_copy
gck_list_unref_free
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index 2e39497..49e71fd 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -56,8 +56,7 @@ struct _GckEnumeratorState {
/* Input to enumerator */
GList *modules;
- GckTokenInfo *match_token;
- GckAttributes *match_attrs;
+ GckUriInfo *match;
guint session_options;
gboolean authenticate;
gchar *password;
@@ -151,12 +150,11 @@ cleanup_state (GckEnumeratorState *args)
args->password = NULL;
}
- gck_token_info_free (args->match_token);
- args->match_token = NULL;
-
- if (args->match_attrs) {
- _gck_attributes_unlock (args->match_attrs);
- gck_attributes_unref (args->match_attrs);
+ if (args->match) {
+ if (args->match->attributes)
+ _gck_attributes_unlock (args->match->attributes);
+ gck_uri_info_free (args->match);
+ args->match = NULL;
}
}
@@ -194,6 +192,7 @@ state_slots (GckEnumeratorState *args, gboolean forward)
GckSlot *slot;
GckModule *module;
GckTokenInfo *token_info;
+ gboolean matched;
g_assert (args->slot == NULL);
@@ -215,15 +214,23 @@ state_slots (GckEnumeratorState *args, gboolean forward)
return rewind_state (args, state_modules);
}
+ matched = TRUE;
+
+ /* Do we have unrecognized matches? */
+ if (args->match->any_unrecognized) {
+ matched = FALSE;
+
/* Are we trying to match the slot? */
- if (args->match_token) {
+ } else if (args->match->token_info) {
/* No match? Go to next slot */
- if (!_gck_token_info_match (args->match_token, token_info)) {
- g_object_unref (slot);
- gck_token_info_free (token_info);
- return state_slots;
- }
+ matched = _gck_token_info_match (args->match->token_info, token_info);
+ }
+
+ if (!matched) {
+ g_object_unref (slot);
+ gck_token_info_free (token_info);
+ return state_slots;
}
module = gck_slot_get_module (slot);
@@ -372,8 +379,8 @@ state_authenticated (GckEnumeratorState *args, gboolean forward)
g_assert (args->want_objects);
g_assert (args->funcs);
- if (args->match_attrs) {
- attrs = _gck_attributes_commit_out (args->match_attrs, &n_attrs);
+ if (args->match->attributes) {
+ attrs = _gck_attributes_commit_out (args->match->attributes, &n_attrs);
} else {
attrs = NULL;
n_attrs = 0;
@@ -494,7 +501,7 @@ gck_enumerator_class_init (GckEnumeratorClass *klass)
GckEnumerator*
_gck_enumerator_new (GList *modules_or_slots, guint session_options,
- GckTokenInfo *match_token, GckAttributes *match_attrs)
+ GckUriInfo *uri_info)
{
GckEnumerator *self;
GckEnumeratorState *state;
@@ -514,11 +521,9 @@ _gck_enumerator_new (GList *modules_or_slots, guint session_options,
state->handler = state_modules;
}
- if (match_attrs) {
- state->match_attrs = gck_attributes_ref (match_attrs);
- _gck_attributes_lock (state->match_attrs);
- }
- state->match_token = match_token;
+ state->match = uri_info;
+ if (uri_info->attributes)
+ _gck_attributes_lock (uri_info->attributes);
return self;
}
diff --git a/gck/gck-misc.c b/gck/gck-misc.c
index 663f9b3..ae8b0d4 100644
--- a/gck/gck-misc.c
+++ b/gck/gck-misc.c
@@ -372,3 +372,42 @@ gck_value_to_boolean (gconstpointer value, gsize length, gboolean *result)
*result = *((CK_BBOOL*)value) ? TRUE : FALSE;
return TRUE;
}
+
+static gboolean
+match_info_string (const gchar *match, const gchar *string)
+{
+ /* NULL matches anything */
+ if (match == NULL)
+ return TRUE;
+
+ if (string == NULL)
+ return FALSE;
+
+ return g_str_equal (match, string);
+}
+
+gboolean
+_gck_module_info_match (GckModuleInfo *match, GckModuleInfo *info)
+{
+ /* Matches two GckModuleInfo for use in PKCS#11 URI's */
+
+ g_return_val_if_fail (match, FALSE);
+ g_return_val_if_fail (info, FALSE);
+
+ return (match_info_string (match->library_description, info->library_description) &&
+ match_info_string (match->manufacturer_id, info->manufacturer_id));
+}
+
+gboolean
+_gck_token_info_match (GckTokenInfo *match, GckTokenInfo *info)
+{
+ /* Matches two GckTokenInfo for use in PKCS#11 URI's */
+
+ g_return_val_if_fail (match, FALSE);
+ g_return_val_if_fail (info, FALSE);
+
+ return (match_info_string (match->label, info->label) &&
+ match_info_string (match->manufacturer_id, info->manufacturer_id) &&
+ match_info_string (match->model, info->model) &&
+ match_info_string (match->serial_number, info->serial_number));
+}
diff --git a/gck/gck-modules.c b/gck/gck-modules.c
index 59ae1c8..c500d55 100644
--- a/gck/gck-modules.c
+++ b/gck/gck-modules.c
@@ -151,32 +151,57 @@ gck_modules_get_slots (GList *modules, gboolean token_present)
GckEnumerator*
gck_modules_enumerate_objects (GList *modules, GckAttributes *attrs, guint session_options)
{
- return _gck_enumerator_new (modules, session_options, NULL, attrs);
+ GckUriInfo *uri_info;
+
+ g_return_val_if_fail (attrs, NULL);
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_ref (attrs);
+
+ return _gck_enumerator_new (modules, session_options, uri_info);
}
GckSlot*
gck_modules_token_for_uri (GList *modules, const gchar *uri, GError **error)
{
- GckTokenInfo *match, *token;
+ GckTokenInfo *token_info;
GckSlot *result = NULL;
+ GckUriInfo *uri_info;
+ GckModuleInfo *module_info;
GList *slots;
GList *m, *s;
+ gboolean matched;
- if (!gck_uri_parse (uri, &match, NULL, error))
+ uri_info = gck_uri_parse (uri, GCK_URI_PARSE_TOKEN, error);
+ if (uri_info == NULL)
return NULL;
- for (m = modules; result == NULL && m != NULL; m = g_list_next (m)) {
- slots = gck_module_get_slots (m->data, TRUE);
- for (s = slots; result == NULL && s != NULL; s = g_list_next (s)) {
- token = gck_slot_get_token_info (s->data);
- if (token && _gck_token_info_match (match, token))
- result = g_object_ref (s->data);
- gck_token_info_free (token);
+ if (!uri_info->any_unrecognized) {
+ for (m = modules; result == NULL && m != NULL; m = g_list_next (m)) {
+ if (uri_info->module_info) {
+ module_info = gck_module_get_info (m->data);
+ matched = _gck_module_info_match (uri_info->module_info, module_info);
+ gck_module_info_free (module_info);
+ if (!matched)
+ continue;
+ }
+
+ slots = gck_module_get_slots (m->data, TRUE);
+ for (s = slots; result == NULL && s != NULL; s = g_list_next (s)) {
+ if (!uri_info->token_info) {
+ result = g_object_ref (s->data);
+ } else {
+ token_info = gck_slot_get_token_info (s->data);
+ if (token_info && _gck_token_info_match (uri_info->token_info, token_info))
+ result = g_object_ref (s->data);
+ gck_token_info_free (token_info);
+ }
+ }
+ gck_list_unref_free (slots);
}
- gck_list_unref_free (slots);
}
- gck_token_info_free (match);
+ gck_uri_info_free (uri_info);
return result;
}
@@ -224,16 +249,12 @@ GckEnumerator*
gck_modules_enumerate_uri (GList *modules, const gchar *uri, guint session_options,
GError **error)
{
- GckTokenInfo *token;
- GckAttributes *attrs;
- GckEnumerator *en;
+ GckUriInfo *uri_info;
- if (!gck_uri_parse (uri, &token, &attrs, error))
+ uri_info = gck_uri_parse (uri, GCK_URI_PARSE_OBJECT, error);
+ if (uri_info == NULL)
return NULL;
- /* Takes ownership of token info */
- en = _gck_enumerator_new (modules, session_options, token, attrs);
- gck_attributes_unref (attrs);
-
- return en;
+ /* Takes ownership of uri_info */
+ return _gck_enumerator_new (modules, session_options, uri_info);
}
diff --git a/gck/gck-private.h b/gck/gck-private.h
index 91727fe..544c4d6 100644
--- a/gck/gck-private.h
+++ b/gck/gck-private.h
@@ -72,14 +72,16 @@ gboolean _gck_module_fire_authenticate_object (GckModule *module,
gchar *label,
gchar **password);
+gboolean _gck_module_info_match (GckModuleInfo *match,
+ GckModuleInfo *module_info);
+
/* -----------------------------------------------------------------------------
* ENUMERATOR
*/
GckEnumerator* _gck_enumerator_new (GList *modules,
guint session_options,
- GckTokenInfo *match_token,
- GckAttributes *match_attrs);
+ GckUriInfo *uri_info);
/* ----------------------------------------------------------------------------
* SLOT
@@ -89,6 +91,12 @@ gboolean _gck_token_info_match (GckTokenInfo *match
GckTokenInfo *info);
/* ----------------------------------------------------------------------------
+ * URI
+ */
+
+GckUriInfo* _gck_uri_info_new (void);
+
+/* ----------------------------------------------------------------------------
* CALL
*/
diff --git a/gck/gck-slot.c b/gck/gck-slot.c
index 8698198..990800d 100644
--- a/gck/gck-slot.c
+++ b/gck/gck-slot.c
@@ -300,33 +300,6 @@ gck_token_info_free (GckTokenInfo *token_info)
g_free (token_info);
}
-static gboolean
-match_token_string (const gchar *match, const gchar *string)
-{
- /* NULL matches anything */
- if (match == NULL)
- return TRUE;
-
- if (string == NULL)
- return FALSE;
-
- return g_str_equal (match, string);
-}
-
-gboolean
-_gck_token_info_match (GckTokenInfo *match, GckTokenInfo *info)
-{
- /* Matches two GckTokenInfo for use in PKCS#11 URI's */
-
- g_return_val_if_fail (match, FALSE);
- g_return_val_if_fail (info, FALSE);
-
- return (match_token_string (match->label, info->label) &&
- match_token_string (match->manufacturer_id, info->manufacturer_id) &&
- match_token_string (match->model, info->model) &&
- match_token_string (match->serial_number, info->serial_number));
-}
-
/**
* GckMechanismInfo:
* @min_key_size: The minimum key size that can be used with this mechanism.
@@ -814,7 +787,14 @@ gck_slot_has_flags (GckSlot *self, gulong flags)
GckEnumerator*
gck_slots_enumerate_objects (GList *slots, GckAttributes *attrs, guint session_options)
{
- return _gck_enumerator_new (slots, session_options, NULL, attrs);
+ GckUriInfo *uri_info;
+
+ g_return_val_if_fail (attrs, NULL);
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_ref (attrs);
+
+ return _gck_enumerator_new (slots, session_options, uri_info);
}
diff --git a/gck/gck-uri.c b/gck/gck-uri.c
index be6e6a1..f43d704 100644
--- a/gck/gck-uri.c
+++ b/gck/gck-uri.c
@@ -34,11 +34,51 @@
#include "egg/egg-hex.h"
/**
- * SECTION:gck-modules
- * @title: GckModule lists
- * @short_description: Dealing with lists of PKCS#11 modules.
+ * SECTION:gck-uri
+ * @title: PKCS11 URIs
+ * @short_description: Parsing and building PKCS\#11 URIs.
*
- * Xxxxx
+ * <ulink href='http://tools.ietf.org/html/draft-pechanec-pkcs11uri-03'>PKCS#11 URIs</ulink>
+ * are a standard for referring to PKCS#11 modules, tokens, or objects. What the
+ * PKCS\#11 URI refers to depends on the context in which it is used.
+ *
+ * A PKCS\#11 URI can always resolve to more than one object, token or module. A
+ * PKCS\#11 URI that refers to a token, would (when used in a context that expects
+ * objects) refer to all the token on that module.
+ *
+ * In most cases the parsing or building of URIs is handled elsewhere in the GCK
+ * library. For example to enumerate objects that match a PKCS\#11 URI use the
+ * gck_modules_enumerate_uri() function. Or to build a PKCS\#11 URI for a given
+ * object, use the gck_object_build_uri() function.
+ *
+ * To parse a PKCS\#11 URI use the gck_uri_parse() function passing in the type of
+ * context in which you're using the URI. To build a URI use the gck_uri_build()
+ * function.
+ **/
+
+/**
+ * GckUriInfo:
+ * @any_unrecognized: whether any parts of the PKCS\#11 URI were unsupported or unrecognized.
+ * @module_info: information about the PKCS\#11 modules matching the URI.
+ * @token_info: information about the PKCS\#11 tokens matching the URI.
+ * @attributes: information about the PKCS\#11 objects matching the URI.
+ *
+ * Information about the contents of a PKCS\#11 URI. Various fields may be %NULL
+ * depending on the context that the URI was parsed for.
+ *
+ * Since PKCS\#11 URIs represent a set which results from the intersections of
+ * all of the URI parts, if @any_recognized is set to %TRUE then usually the URI
+ * should be treated as not matching anything.
+ */
+
+/**
+ * GckUriContext:
+ * @GCK_URI_CONTEXT_MODULE: the URI will be used to match modules.
+ * @GCK_URI_CONTEXT_TOKEN: the URI will be used to match tokens.
+ * @GCK_URI_CONTEXT_OBJECT: the URI will be used to match objects.
+ * @GCK_URI_CONTEXT_ANY: parse all recognized components of the URI.
+ *
+ * Which context the PKCS\#11 URI will be used in.
*/
#define URI_PREFIX "pkcs11:"
@@ -58,6 +98,12 @@ gck_uri_get_error_quark (void)
return domain;
}
+GckUriInfo*
+_gck_uri_info_new (void)
+{
+ return g_slice_new0 (GckUriInfo);
+}
+
static gint
parse_string_attribute (const gchar *name, const gchar *start, const gchar *end,
GckAttributes *attrs, GError **error)
@@ -177,14 +223,60 @@ parse_token_attribute (const gchar *name, const gchar *start, const gchar *end,
return 1;
}
-gboolean
-gck_uri_parse (const gchar *uri, GckTokenInfo **token, GckAttributes **attrs, GError **error)
+static gint
+parse_library_attribute (const gchar *name, const gchar *start, const gchar *end,
+ GckModuleInfo *library, GError **error)
+{
+ gchar **value;
+ gchar *string;
+
+ g_assert (name);
+ g_assert (start);
+ g_assert (end);
+ g_assert (library);
+
+ if (g_str_equal (name, "library-description"))
+ value = &(library->library_description);
+ else if (g_str_equal (name, "manufacturer"))
+ value = &(library->manufacturer_id);
+ else
+ return 0;
+
+ string = g_uri_unescape_segment (start, end, "");
+ if (string == NULL) {
+ g_set_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING,
+ _("The URI has invalid syntax. The '%s' field encoding is invalid."), name);
+ return -1;
+ }
+
+ g_free (*value);
+ *value = string;
+
+ return 1;
+}
+
+/**
+ * gck_uri_parse:
+ * @uri: the URI to parse.
+ * @flags: the context in which the URI will be used.
+ * @error: a #GError, or %NULL.
+ *
+ * Parse a PKCS\#11 URI for use in a given context.
+ *
+ * The result will contain the fields that are relevant for
+ * the given context. See #GckUriInfo for more info.
+ * Other fields will be set to %NULL.
+ *
+ * Return value: a newly allocated #GckUriInfo, which should be freed with
+ * gck_uri_info_free().
+ */
+GckUriInfo*
+gck_uri_parse (const gchar *uri, GckUriParseFlags flags, GError **error)
{
- GckAttributes *rattrs = NULL;
- GckTokenInfo *rtoken = NULL;
const gchar *spos, *epos;
gchar *key = NULL;
gboolean ret = FALSE;
+ GckUriInfo *uri_info = NULL;
gint res;
g_return_val_if_fail (uri, FALSE);
@@ -197,8 +289,14 @@ gck_uri_parse (const gchar *uri, GckTokenInfo **token, GckAttributes **attrs, GE
}
uri += N_URI_PREFIX;
- rattrs = gck_attributes_new ();
- rtoken = g_new0 (GckTokenInfo, 1);
+
+ uri_info = _gck_uri_info_new ();
+ if ((flags & GCK_URI_PARSE_MODULE) == GCK_URI_PARSE_MODULE)
+ uri_info->module_info = g_new0 (GckModuleInfo, 1);
+ if ((flags & GCK_URI_PARSE_TOKEN) == GCK_URI_PARSE_TOKEN)
+ uri_info->token_info = g_new0 (GckTokenInfo, 1);
+ if ((flags & GCK_URI_PARSE_OBJECT) == GCK_URI_PARSE_OBJECT)
+ uri_info->attributes = gck_attributes_new ();
for (;;) {
spos = strchr (uri, ';');
@@ -220,15 +318,21 @@ gck_uri_parse (const gchar *uri, GckTokenInfo **token, GckAttributes **attrs, GE
key = g_strndup (uri, epos - uri);
epos++;
- res = parse_string_attribute (key, epos, spos, rattrs, error);
- if (res == 0)
- res = parse_binary_attribute (key, epos, spos, rattrs, error);
- if (res == 0)
- res = parse_token_attribute (key, epos, spos, rtoken, error);
+ res = 0;
+ if (uri_info->attributes)
+ res = parse_string_attribute (key, epos, spos, uri_info->attributes, error);
+ if (res == 0 && uri_info->attributes)
+ res = parse_binary_attribute (key, epos, spos, uri_info->attributes, error);
+ if (res == 0 && uri_info->token_info)
+ res = parse_token_attribute (key, epos, spos, uri_info->token_info, error);
+ if (res == 0 && uri_info->module_info)
+ res = parse_library_attribute (key, epos, spos, uri_info->module_info, error);
if (res < 0)
goto cleanup;
- if (res == 0)
- g_message ("Ignoring unsupported field '%s'", key);
+ if (res == 0) {
+ g_message ("Ignoring unrecognized or unsupported field '%s'", key);
+ uri_info->any_unrecognized = TRUE;
+ }
if (*spos == '\0')
break;
@@ -238,21 +342,13 @@ gck_uri_parse (const gchar *uri, GckTokenInfo **token, GckAttributes **attrs, GE
ret = TRUE;
cleanup:
- if (ret && token) {
- *token = rtoken;
- rtoken = NULL;
- }
- if (ret && attrs) {
- *attrs = rattrs;
- rattrs = NULL;
+ if (!ret) {
+ gck_uri_info_free (uri_info);
+ uri_info = NULL;
}
- gck_token_info_free (rtoken);
- if (rattrs)
- gck_attributes_unref (rattrs);
-
g_free (key);
- return ret;
+ return uri_info;
}
static void
@@ -267,8 +363,6 @@ build_string_attribute (const gchar *name, const gchar *value,
if (!value)
return;
- if (!value[0])
- return;
segment = g_uri_escape_string (value, "", FALSE);
if (!*first)
@@ -290,10 +384,7 @@ build_binary_attribute (const gchar *name, gconstpointer data, gsize n_data,
g_assert (first);
g_assert (result);
g_assert (name);
-
- if (!n_data)
- return;
- g_assert (data);
+ g_assert (!n_data || data);
segment = egg_hex_encode_full (data, n_data, FALSE, ':', 1);
if (!*first)
@@ -306,8 +397,17 @@ build_binary_attribute (const gchar *name, gconstpointer data, gsize n_data,
g_free (segment);
}
+/**
+ * gck_uri_build:
+ * @uri_info: the info to build the URI from.
+ *
+ * Build a PKCS\#11 URI. Any set fields of @uri_info will be used to build
+ * the URI.
+ *
+ * Return value: a newly allocated string containing a PKCS\#11 URI.
+ */
gchar*
-gck_uri_build (GckTokenInfo *token, GckAttributes *attrs)
+gck_uri_build (GckUriInfo *uri_info)
{
GckAttribute *attr;
GString *result;
@@ -315,21 +415,28 @@ gck_uri_build (GckTokenInfo *token, GckAttributes *attrs)
gulong klass;
gboolean first = TRUE;
+ g_return_val_if_fail (uri_info, NULL);
+
result = g_string_new (URI_PREFIX);
- if (token) {
- build_string_attribute ("model", token->model, result, &first);
- build_string_attribute ("manufacturer", token->manufacturer_id, result, &first);
- build_string_attribute ("serial", token->serial_number, result, &first);
- build_string_attribute ("token", token->label, result, &first);
+ if (uri_info->module_info) {
+ build_string_attribute ("library-description", uri_info->module_info->library_description, result, &first);
+ build_string_attribute ("library-manufacturer", uri_info->module_info->manufacturer_id, result, &first);
+ }
+
+ if (uri_info->token_info) {
+ build_string_attribute ("model", uri_info->token_info->model, result, &first);
+ build_string_attribute ("manufacturer", uri_info->token_info->manufacturer_id, result, &first);
+ build_string_attribute ("serial", uri_info->token_info->serial_number, result, &first);
+ build_string_attribute ("token", uri_info->token_info->label, result, &first);
}
- if (attrs) {
- if (gck_attributes_find_string (attrs, CKA_LABEL, &value)) {
+ if (uri_info->attributes) {
+ if (gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value)) {
build_string_attribute ("object", value, result, &first);
g_free (value);
}
- if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass)) {
+ if (gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass)) {
if (klass == CKO_CERTIFICATE)
build_string_attribute ("objecttype", "cert", result, &first);
else if (klass == CKO_PUBLIC_KEY)
@@ -341,10 +448,30 @@ gck_uri_build (GckTokenInfo *token, GckAttributes *attrs)
else if (klass == CKO_DATA)
build_string_attribute ("objecttype", "data", result, &first);
}
- attr = gck_attributes_find (attrs, CKA_ID);
+ attr = gck_attributes_find (uri_info->attributes, CKA_ID);
if (attr != NULL)
build_binary_attribute ("id", attr->value, attr->length, result, &first);
}
return g_string_free (result, FALSE);
}
+
+/**
+ * gck_uri_info_free:
+ * @uri_info: URI info to free.
+ *
+ * Free a #GckUriInfo.
+ */
+void
+gck_uri_info_free (GckUriInfo *uri_info)
+{
+ if (uri_info) {
+ if (uri_info->attributes)
+ gck_attributes_unref (uri_info->attributes);
+ if (uri_info->module_info)
+ gck_module_info_free (uri_info->module_info);
+ if (uri_info->token_info)
+ gck_token_info_free (uri_info->token_info);
+ g_slice_free (GckUriInfo, uri_info);
+ }
+}
diff --git a/gck/gck.h b/gck/gck.h
index 4a4a564..0f62be0 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -1300,17 +1300,34 @@ enum {
GCK_URI_BAD_SYNTAX = 3
};
+typedef enum {
+ GCK_URI_PARSE_MODULE = (1 << 1),
+ GCK_URI_PARSE_TOKEN = (1 << 2) | GCK_URI_PARSE_MODULE,
+ GCK_URI_PARSE_OBJECT = (1 << 3) | GCK_URI_PARSE_TOKEN,
+ GCK_URI_PARSE_ANY = 0xFFFFFFFF,
+} GckUriParseFlags;
+
+typedef struct _GckUriInfo {
+ gboolean any_unrecognized;
+ GckModuleInfo *module_info;
+ GckTokenInfo *token_info;
+ GckAttributes *attributes;
+
+ /*< private >*/
+ gpointer dummy[4];
+} GckUriInfo;
+
#define GCK_URI_ERROR (gck_uri_get_error_quark ())
GQuark gck_uri_get_error_quark (void);
-gchar* gck_uri_build (GckTokenInfo *token,
- GckAttributes *attrs);
+gchar* gck_uri_build (GckUriInfo *uri_info);
-gboolean gck_uri_parse (const gchar *uri,
- GckTokenInfo **token,
- GckAttributes **attrs,
- GError **err);
+GckUriInfo* gck_uri_parse (const gchar *uri,
+ GckUriParseFlags flags,
+ GError **error);
+
+void gck_uri_info_free (GckUriInfo *uri_info);
G_END_DECLS
diff --git a/gck/tests/gck-test.h b/gck/tests/gck-test.h
deleted file mode 100644
index 1401d82..0000000
--- a/gck/tests/gck-test.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef GCK_TEST_H_
-#define GCK_TEST_H_
-
-#include "gck.h"
-#include "gck-mock.h"
-
-#define FAIL_RES(res, e) do { \
- g_assert ((res) ? FALSE : TRUE); \
- g_assert ((e) && (e)->message && "error should be set"); \
- g_clear_error (&e); \
- } while (0)
-
-#define SUCCESS_RES(res, err) do { \
- if (!(res)) g_printerr ("error: %s\n", err && err->message ? err->message : ""); \
- g_assert ((res) ? TRUE : FALSE && "should have succeeded"); \
- g_clear_error (&err); \
- } while(0)
-
-#endif /* GCK_TEST_H_ */
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index 2d86563..a9148f2 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -31,20 +31,24 @@ TESTING_TEARDOWN(enumerator)
TESTING_TEST(enumerator_create)
{
+ GckUriInfo *uri_info;
GckEnumerator *en;
- en = _gck_enumerator_new (modules, 0, NULL, NULL);
+ uri_info = _gck_uri_info_new ();
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
g_object_unref (en);
}
TESTING_TEST(enumerator_create_slots)
{
+ GckUriInfo *uri_info;
GckEnumerator *en;
GList *slots;
+ uri_info = _gck_uri_info_new ();
slots = gck_module_get_slots (module, FALSE);
- en = _gck_enumerator_new (slots, 0, NULL, NULL);
+ en = _gck_enumerator_new (slots, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
g_object_unref (en);
gck_list_unref_free (slots);
@@ -52,11 +56,13 @@ TESTING_TEST(enumerator_create_slots)
TESTING_TEST(enumerator_next)
{
+ GckUriInfo *uri_info;
GError *error = NULL;
GckEnumerator *en;
GckObject *obj;
- en = _gck_enumerator_new (modules, 0, NULL, NULL);
+ uri_info = _gck_uri_info_new ();
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
obj = gck_enumerator_next (en, NULL, &error);
@@ -68,13 +74,15 @@ TESTING_TEST(enumerator_next)
TESTING_TEST(enumerator_next_slots)
{
+ GckUriInfo *uri_info;
GError *error = NULL;
GList *slots = NULL;
GckEnumerator *en;
GckObject *obj;
+ uri_info = _gck_uri_info_new ();
slots = gck_module_get_slots (module, FALSE);
- en = _gck_enumerator_new (slots, 0, NULL, NULL);
+ en = _gck_enumerator_new (slots, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
obj = gck_enumerator_next (en, NULL, &error);
@@ -87,11 +95,13 @@ TESTING_TEST(enumerator_next_slots)
TESTING_TEST(enumerator_next_and_resume)
{
+ GckUriInfo *uri_info;
GError *error = NULL;
GckEnumerator *en;
GckObject *obj, *obj2;
- en = _gck_enumerator_new (modules, 0, NULL, NULL);
+ uri_info = _gck_uri_info_new ();
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
obj = gck_enumerator_next (en, NULL, &error);
@@ -111,11 +121,13 @@ TESTING_TEST(enumerator_next_and_resume)
TESTING_TEST(enumerator_next_n)
{
+ GckUriInfo *uri_info;
GError *error = NULL;
GckEnumerator *en;
GList *objects, *l;
- en = _gck_enumerator_new (modules, 0, NULL, NULL);
+ uri_info = _gck_uri_info_new ();
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
objects = gck_enumerator_next_n (en, -1, NULL, &error);
@@ -138,12 +150,14 @@ fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
TESTING_TEST(enumerator_next_async)
{
+ GckUriInfo *uri_info;
GAsyncResult *result = NULL;
GError *error = NULL;
GckEnumerator *en;
GList *objects, *l;
- en = _gck_enumerator_new (modules, 0, NULL, NULL);
+ uri_info = _gck_uri_info_new ();
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
gck_enumerator_next_async (en, -1, NULL, fetch_async_result, &result);
@@ -163,16 +177,16 @@ TESTING_TEST(enumerator_next_async)
TESTING_TEST(enumerator_attributes)
{
- GckAttributes *attrs;
+ GckUriInfo *uri_info;
GError *error = NULL;
GckEnumerator *en;
GList *objects;
- attrs = gck_attributes_new ();
- gck_attributes_add_string (attrs, CKA_LABEL, "Private Capitalize Key");
- en = _gck_enumerator_new (modules, 0, NULL, attrs);
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_new ();
+ gck_attributes_add_string (uri_info->attributes, CKA_LABEL, "Private Capitalize Key");
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
- gck_attributes_unref (attrs);
objects = gck_enumerator_next_n (en, -1, NULL, &error);
SUCCESS_RES (objects, error);
@@ -185,14 +199,15 @@ TESTING_TEST(enumerator_attributes)
TESTING_TEST(enumerator_token_match)
{
- GckTokenInfo *token;
+ GckUriInfo *uri_info;
GError *error = NULL;
GckEnumerator *en;
GList *objects;
- token = g_new0 (GckTokenInfo, 1);
- token->label = g_strdup ("Invalid token name");
- en = _gck_enumerator_new (modules, 0, token, NULL);
+ uri_info = _gck_uri_info_new ();
+ uri_info->token_info = g_new0 (GckTokenInfo, 1);
+ uri_info->token_info->label = g_strdup ("Invalid token name");
+ en = _gck_enumerator_new (modules, 0, uri_info);
g_assert (GCK_IS_ENUMERATOR (en));
objects = gck_enumerator_next_n (en, -1, NULL, &error);
diff --git a/gck/tests/test-gck-uri.c b/gck/tests/test-gck-uri.c
index 03b8a2b..340d5db 100644
--- a/gck/tests/test-gck-uri.c
+++ b/gck/tests/test-gck-uri.c
@@ -1,3 +1,25 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* test-gck-uri.c: Test routines for PKCS#11 URIs
+
+ Copyright (C) 2011, Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@collabora.co.uk>
+*/
#include <glib.h>
#include <string.h>
@@ -19,135 +41,188 @@ TESTING_TEARDOWN(uri)
TESTING_TEST(uri_parse)
{
GError *error = NULL;
- if (!gck_uri_parse ("pkcs11:", NULL, NULL, &error))
- g_assert_not_reached ();
+ GckUriInfo *uri_info;
+
+ uri_info = gck_uri_parse ("pkcs11:", GCK_URI_PARSE_MODULE, &error);
+ g_assert (uri_info != NULL);
+ g_assert_no_error (error);
+
+ g_assert (uri_info->attributes == NULL);
+ g_assert (uri_info->token_info == NULL);
+
+ g_assert (uri_info->module_info != NULL);
+ g_assert (uri_info->module_info->library_description == NULL);
+ g_assert (uri_info->module_info->manufacturer_id == NULL);
+
+ gck_uri_info_free (uri_info);
}
TESTING_TEST(uri_parse_bad_scheme)
{
GError *error = NULL;
- if (gck_uri_parse ("http:\\example.com\test", NULL, NULL, &error))
- g_assert_not_reached ();
- g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_PREFIX));
+ GckUriInfo *uri_info;
+
+ uri_info = gck_uri_parse ("http:\\example.com\test", GCK_URI_PARSE_ANY, &error);
+ g_assert (uri_info == NULL);
+ g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_PREFIX);
g_error_free (error);
}
TESTING_TEST(uri_parse_with_label)
{
GError *error = NULL;
- GckAttributes *attrs;
+ GckUriInfo *uri_info;
gchar *value;
- if (!gck_uri_parse ("pkcs11:object=Test%20Label", NULL, &attrs, &error))
- g_assert_not_reached ();
+ uri_info = gck_uri_parse ("pkcs11:object=Test%20Label", GCK_URI_PARSE_ANY, &error);
+ g_assert (uri_info != NULL);
+ g_assert (uri_info->attributes != NULL);
- if (!gck_attributes_find_string (attrs, CKA_LABEL, &value))
+ if (!gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value))
g_assert_not_reached ();
g_assert_cmpstr (value, ==, "Test Label");
g_free (value);
+
+ gck_uri_info_free (uri_info);
}
+
TESTING_TEST(uri_parse_with_label_and_klass)
{
GError *error = NULL;
- GckAttributes *attrs;
+ GckUriInfo *uri_info;
gchar *value;
gulong klass;
- if (!gck_uri_parse ("pkcs11:object=Test%20Label;objecttype=cert", NULL, &attrs, &error))
- g_assert_not_reached ();
+ uri_info = gck_uri_parse ("pkcs11:object=Test%20Label;objecttype=cert", GCK_URI_PARSE_ANY, &error);
+ g_assert (uri_info);
+ g_assert (uri_info->attributes);
- if (!gck_attributes_find_string (attrs, CKA_LABEL, &value))
+ if (!gck_attributes_find_string (uri_info->attributes, CKA_LABEL, &value))
g_assert_not_reached ();
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
+ if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass))
g_assert_not_reached ();
g_assert_cmpstr (value, ==, "Test Label");
g_assert (klass == CKO_CERTIFICATE);
g_free (value);
+
+ gck_uri_info_free (uri_info);
}
TESTING_TEST(uri_parse_with_id)
{
GError *error = NULL;
- GckAttributes *attrs;
GckAttribute *attr;
+ GckUriInfo *uri_info;
- if (!gck_uri_parse ("pkcs11:id=54:45:53:54", NULL, &attrs, &error))
- g_assert_not_reached ();
+ uri_info = gck_uri_parse ("pkcs11:id=54:45:53:54", GCK_URI_PARSE_OBJECT, &error);
+ g_assert (uri_info != NULL);
+ g_assert (uri_info->attributes != NULL);
- attr = gck_attributes_find (attrs, CKA_ID);
+ attr = gck_attributes_find (uri_info->attributes, CKA_ID);
g_assert (attr);
g_assert (attr->value);
g_assert (attr->length == 4);
g_assert (memcmp (attr->value, "TEST", 4) == 0);
- gck_attributes_unref (attrs);
+ gck_uri_info_free (uri_info);
}
TESTING_TEST(uri_parse_with_bad_string_encoding)
{
GError *error = NULL;
- if (gck_uri_parse ("pkcs11:object=Test%", NULL, NULL, &error))
- g_assert_not_reached ();
- g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING));
+ GckUriInfo *uri_info;
+
+ uri_info = gck_uri_parse ("pkcs11:object=Test%", GCK_URI_PARSE_OBJECT, &error);
+ g_assert (uri_info == NULL);
+ g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING);
g_error_free (error);
}
TESTING_TEST(uri_parse_with_bad_binary_encoding)
{
GError *error = NULL;
- if (gck_uri_parse ("pkcs11:id=xxxxx", NULL, NULL, &error))
- g_assert_not_reached ();
- g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING));
+ GckUriInfo *uri_info;
+ uri_info = gck_uri_parse ("pkcs11:id=xxxxx", GCK_URI_PARSE_ANY, &error);
+ g_assert (!uri_info);
+ g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING);
g_error_free (error);
}
TESTING_TEST(uri_parse_with_token)
{
GError *error = NULL;
- GckTokenInfo *token = NULL;
-
- if (!gck_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me",
- &token, NULL, &error))
- g_assert_not_reached ();
-
- g_assert (token);
- g_assert_cmpstr (token->label, ==, "Token Label");
- g_assert_cmpstr (token->serial_number, ==, "3333");
- g_assert_cmpstr (token->model, ==, "Deluxe");
- g_assert_cmpstr (token->manufacturer_id, ==, "Me");
- gck_token_info_free (token);
+ GckUriInfo *uri_info = NULL;
+
+ uri_info = gck_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me",
+ GCK_URI_PARSE_TOKEN, &error);
+
+ g_assert (uri_info);
+ g_assert (uri_info->token_info);
+ g_assert_cmpstr (uri_info->token_info->label, ==, "Token Label");
+ g_assert_cmpstr (uri_info->token_info->serial_number, ==, "3333");
+ g_assert_cmpstr (uri_info->token_info->model, ==, "Deluxe");
+ g_assert_cmpstr (uri_info->token_info->manufacturer_id, ==, "Me");
+ gck_uri_info_free (uri_info);
}
TESTING_TEST(uri_parse_with_token_bad_encoding)
{
GError *error = NULL;
+ GckUriInfo *uri_info;
- if (gck_uri_parse ("pkcs11:token=Token%", NULL, NULL, &error))
- g_assert_not_reached ();
-
- g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING));
+ uri_info = gck_uri_parse ("pkcs11:token=Token%", GCK_URI_PARSE_TOKEN, &error);
+ g_assert (!uri_info);
+ g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING);
g_error_free (error);
}
TESTING_TEST(uri_parse_with_bad_syntax)
{
GError *error = NULL;
+ GckUriInfo *uri_info;
- if (gck_uri_parse ("pkcs11:token", NULL, NULL, &error))
- g_assert_not_reached ();
-
+ uri_info = gck_uri_parse ("pkcs11:token", GCK_URI_PARSE_ANY, &error);
+ g_assert (uri_info == NULL);
g_assert (g_error_matches (error, GCK_URI_ERROR, GCK_URI_BAD_SYNTAX));
g_error_free (error);
}
+TESTING_TEST(uri_parse_with_library)
+{
+ GError *error = NULL;
+ GckUriInfo *uri_info = NULL;
+
+ uri_info = gck_uri_parse ("pkcs11:library-description=The%20Library;manufacturer=Me",
+ GCK_URI_PARSE_MODULE, &error);
+
+ g_assert (uri_info);
+ g_assert (uri_info->module_info);
+ g_assert_cmpstr (uri_info->module_info->manufacturer_id, ==, "Me");
+ g_assert_cmpstr (uri_info->module_info->library_description, ==, "The Library");
+ gck_uri_info_free (uri_info);
+}
+
+TESTING_TEST(uri_parse_with_library_bad_encoding)
+{
+ GError *error = NULL;
+ GckUriInfo *uri_info;
+
+ uri_info = gck_uri_parse ("pkcs11:library-description=Library%", GCK_URI_PARSE_MODULE, &error);
+ g_assert (!uri_info);
+ g_assert_error (error, GCK_URI_ERROR, GCK_URI_BAD_ENCODING);
+ g_error_free (error);
+}
+
TESTING_TEST(uri_build_empty)
{
- gchar *uri = NULL;
+ GckUriInfo uri_info;
+ gchar *uri;
- uri = gck_uri_build (NULL, NULL);
+ memset (&uri_info, 0, sizeof (uri_info));
+ uri = gck_uri_build (&uri_info);
g_assert_cmpstr (uri, ==, "pkcs11:");
g_free (uri);
}
@@ -155,25 +230,27 @@ TESTING_TEST(uri_build_empty)
TESTING_TEST(uri_build_with_token_info)
{
gchar *uri = NULL;
- GckTokenInfo *token;
- GckTokenInfo *check;
+ GckUriInfo uri_info;
+ GckUriInfo *check;
- token = g_new0 (GckTokenInfo, 1);
- token->label = g_strdup ("The Label");
- token->serial_number = g_strdup ("44444");
- token->manufacturer_id = g_strdup ("Me");
- token->model = g_strdup ("Deluxe");
+ memset (&uri_info, 0, sizeof (uri_info));
+ uri_info.token_info = g_new0 (GckTokenInfo, 1);
+ uri_info.token_info->label = g_strdup ("The Label");
+ uri_info.token_info->serial_number = g_strdup ("44444");
+ uri_info.token_info->manufacturer_id = g_strdup ("Me");
+ uri_info.token_info->model = g_strdup ("Deluxe");
- uri = gck_uri_build (token, NULL);
+ uri = gck_uri_build (&uri_info);
g_assert (uri);
- if (!gck_uri_parse (uri, &check, NULL, NULL))
- g_assert_not_reached ();
+ check = gck_uri_parse (uri, GCK_URI_PARSE_TOKEN, NULL);
+ g_assert (check);
+ g_assert (check->token_info);
- g_assert (_gck_token_info_match (token, check));
+ g_assert (_gck_token_info_match (uri_info.token_info, check->token_info));
- gck_token_info_free (check);
- gck_token_info_free (token);
+ gck_token_info_free (uri_info.token_info);
+ gck_uri_info_free (check);
g_assert (g_str_has_prefix (uri, "pkcs11:"));
g_assert (strstr (uri, "token=The%20Label"));
@@ -184,41 +261,85 @@ TESTING_TEST(uri_build_with_token_info)
g_free (uri);
}
+TESTING_TEST(uri_build_with_token_null_info)
+{
+ gchar *uri = NULL;
+ GckUriInfo uri_info;
+
+ memset (&uri_info, 0, sizeof (uri_info));
+ uri_info.token_info = g_new0 (GckTokenInfo, 1);
+ uri_info.token_info->label = g_strdup ("The Label");
+
+ uri = gck_uri_build (&uri_info);
+ g_assert (uri);
+
+ g_assert (g_str_has_prefix (uri, "pkcs11:"));
+ g_assert (strstr (uri, "token=The%20Label"));
+ g_assert (!strstr (uri, "serial="));
+
+ gck_token_info_free (uri_info.token_info);
+ g_free (uri);
+}
+
+TESTING_TEST(uri_build_with_token_empty_info)
+{
+ gchar *uri = NULL;
+ GckUriInfo uri_info;
+
+ memset (&uri_info, 0, sizeof (uri_info));
+ uri_info.token_info = g_new0 (GckTokenInfo, 1);
+ uri_info.token_info->label = g_strdup ("The Label");
+ uri_info.token_info->serial_number = g_strdup ("");
+
+ uri = gck_uri_build (&uri_info);
+ g_assert (uri);
+
+ g_assert (g_str_has_prefix (uri, "pkcs11:"));
+ g_assert (strstr (uri, "token=The%20Label"));
+ g_assert (strstr (uri, "serial="));
+
+ gck_token_info_free (uri_info.token_info);
+ g_free (uri);
+}
+
TESTING_TEST(uri_build_with_attributes)
{
gchar *uri = NULL;
- GckAttributes *attrs;
+ GckUriInfo uri_info;
+ GckUriInfo *check;
gchar *string;
gulong value;
GckAttribute *attr;
- attrs = gck_attributes_new ();
- gck_attributes_add_string (attrs, CKA_LABEL, "The Label");
- gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_DATA);
- gck_attributes_add_data (attrs, CKA_ID, "TEST", 4);
+ memset (&uri_info, 0, sizeof (uri_info));
+ uri_info.attributes = gck_attributes_new ();
+ gck_attributes_add_string (uri_info.attributes, CKA_LABEL, "The Label");
+ gck_attributes_add_ulong (uri_info.attributes, CKA_CLASS, CKO_DATA);
+ gck_attributes_add_data (uri_info.attributes, CKA_ID, "TEST", 4);
- uri = gck_uri_build (NULL, attrs);
+ uri = gck_uri_build (&uri_info);
g_assert (uri);
- gck_attributes_unref (attrs);
+ gck_attributes_unref (uri_info.attributes);
- if (!gck_uri_parse (uri, NULL, &attrs, NULL))
- g_assert_not_reached ();
+ check = gck_uri_parse (uri, GCK_URI_PARSE_ANY, NULL);
+ g_assert (check);
+ g_assert (check->attributes);
- if (!gck_attributes_find_string (attrs, CKA_LABEL, &string))
+ if (!gck_attributes_find_string (check->attributes, CKA_LABEL, &string))
g_assert_not_reached ();
g_assert_cmpstr (string, ==, "The Label");
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &value))
+ if (!gck_attributes_find_ulong (check->attributes, CKA_CLASS, &value))
g_assert_not_reached ();
g_assert (value == CKO_DATA);
- attr = gck_attributes_find (attrs, CKA_ID);
+ attr = gck_attributes_find (check->attributes, CKA_ID);
g_assert (attr);
g_assert (attr->length == 4);
g_assert (memcmp (attr->value, "TEST", 4) == 0);
- gck_attributes_unref (attrs);
+ gck_uri_info_free (check);
g_assert (g_str_has_prefix (uri, "pkcs11:"));
g_assert (strstr (uri, "object=The%20Label"));
@@ -227,3 +348,143 @@ TESTING_TEST(uri_build_with_attributes)
g_free (uri);
}
+
+TESTING_TEST (uri_parse_private_key)
+{
+ GckUriInfo *uri_info;
+ GError *error = NULL;
+ gulong klass;
+
+ uri_info = gck_uri_parse ("pkcs11:objecttype=private", GCK_URI_PARSE_OBJECT, &error);
+ g_assert (uri_info);
+ g_assert_no_error (error);
+
+ g_assert (uri_info->attributes);
+ if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass))
+ g_assert_not_reached ();
+ gck_assert_cmpulong (klass, ==, CKO_PRIVATE_KEY);
+
+ gck_uri_info_free (uri_info);
+}
+
+TESTING_TEST (uri_parse_parse_secret_key)
+{
+ GckUriInfo *uri_info;
+ GError *error = NULL;
+ gulong klass;
+
+ uri_info = gck_uri_parse ("pkcs11:objecttype=secretkey", GCK_URI_PARSE_OBJECT, &error);
+ g_assert (uri_info);
+ g_assert_no_error (error);
+
+ g_assert (uri_info->attributes);
+ if (!gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass))
+ g_assert_not_reached ();
+ gck_assert_cmpulong (klass, ==, CKO_SECRET_KEY);
+
+ gck_uri_info_free (uri_info);
+}
+
+
+TESTING_TEST (uri_parse_parse_unknown_objecttype)
+{
+ GckUriInfo *uri_info;
+ GError *error = NULL;
+ gulong klass;
+
+ uri_info = gck_uri_parse ("pkcs11:objecttype=unknown", GCK_URI_PARSE_OBJECT, &error);
+ g_assert (uri_info);
+ g_assert_no_error (error);
+
+ g_assert (uri_info->attributes);
+ g_assert (uri_info->any_unrecognized == TRUE);
+ if (gck_attributes_find_ulong (uri_info->attributes, CKA_CLASS, &klass))
+ g_assert_not_reached ();
+
+ gck_uri_info_free (uri_info);
+}
+
+TESTING_TEST (uri_build_objecttype_cert)
+{
+ GckUriInfo *uri_info;
+ gchar *uri;
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_new ();
+ gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_CERTIFICATE);
+
+ uri = gck_uri_build (uri_info);
+ g_assert (uri);
+ g_assert (strstr (uri, "objecttype=cert"));
+
+ gck_uri_info_free (uri_info);
+ g_free (uri);
+}
+
+TESTING_TEST (uri_build_objecttype_private)
+{
+ GckUriInfo *uri_info;
+ gchar *uri;
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_new ();
+ gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_PRIVATE_KEY);
+
+ uri = gck_uri_build (uri_info);
+ g_assert (uri);
+ g_assert (strstr (uri, "objecttype=private"));
+
+ gck_uri_info_free (uri_info);
+ g_free (uri);
+}
+
+TESTING_TEST (uri_build_objecttype_public)
+{
+ GckUriInfo *uri_info;
+ gchar *uri;
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_new ();
+ gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_PUBLIC_KEY);
+
+ uri = gck_uri_build (uri_info);
+ g_assert (uri);
+ g_assert (strstr (uri, "objecttype=public"));
+
+ gck_uri_info_free (uri_info);
+ g_free (uri);
+}
+
+TESTING_TEST (uri_build_objecttype_secret)
+{
+ GckUriInfo *uri_info;
+ gchar *uri;
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->attributes = gck_attributes_new ();
+ gck_attributes_add_ulong (uri_info->attributes, CKA_CLASS, CKO_SECRET_KEY);
+
+ uri = gck_uri_build (uri_info);
+ g_assert (uri);
+ g_assert (strstr (uri, "objecttype=secretkey"));
+
+ gck_uri_info_free (uri_info);
+ g_free (uri);
+}
+
+TESTING_TEST (uri_build_with_library)
+{
+ GckUriInfo *uri_info;
+ gchar *uri;
+
+ uri_info = _gck_uri_info_new ();
+ uri_info->module_info = g_new0 (GckModuleInfo, 1);
+ uri_info->module_info->library_description = g_strdup ("The Description");
+
+ uri = gck_uri_build (uri_info);
+ g_assert (uri);
+ g_assert (strstr (uri, "library-description=The%20Description"));
+
+ gck_uri_info_free (uri_info);
+ g_free (uri);
+}
diff --git a/gck/tests/test-gck.h b/gck/tests/test-gck.h
new file mode 100644
index 0000000..e14d1c8
--- /dev/null
+++ b/gck/tests/test-gck.h
@@ -0,0 +1,43 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gck-uri.c - the GObject PKCS#11 wrapper library
+
+ Copyright (C) 2011, Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@collabora.co.uk>
+*/
+
+#ifndef TEST_GCK_H_
+#define TEST_GCK_H_
+
+#include "gck.h"
+#include "gck-mock.h"
+#include "gck-test.h"
+
+#define FAIL_RES(res, e) do { \
+ g_assert ((res) ? FALSE : TRUE); \
+ g_assert ((e) && (e)->message && "error should be set"); \
+ g_clear_error (&e); \
+ } while (0)
+
+#define SUCCESS_RES(res, err) do { \
+ if (!(res)) g_printerr ("error: %s\n", err && err->message ? err->message : ""); \
+ g_assert ((res) ? TRUE : FALSE && "should have succeeded"); \
+ g_clear_error (&err); \
+ } while(0)
+
+#endif /* TEST_GCK_H_ */