]> granicus.if.org Git - p11-kit/commitdiff
uri: Support vendor query attributes
authorDaiki Ueno <dueno@redhat.com>
Mon, 20 Feb 2017 10:01:21 +0000 (11:01 +0100)
committerDaiki Ueno <ueno@gnu.org>
Tue, 21 Feb 2017 16:46:04 +0000 (17:46 +0100)
If an unknown attribute is present in the query part of the PKCS#11 URI,
the parser treated it as unrecognized and subsequent matches failed.

Instead, keep track of such attributes and provide a set of API to deal
with them.

doc/manual/p11-kit-sections.txt
p11-kit/test-uri.c
p11-kit/uri.c
p11-kit/uri.h

index a1fdeb5e1396a08438461eabaff53d3ba643974b..c1c1df1e333ad0e2ab83f1eecf4c888d6b5000e5 100644 (file)
@@ -34,6 +34,8 @@ p11_kit_uri_get_module_name
 p11_kit_uri_set_module_name
 p11_kit_uri_get_module_path
 p11_kit_uri_set_module_path
+p11_kit_uri_get_vendor_query
+p11_kit_uri_set_vendor_query
 p11_kit_uri_format
 p11_kit_uri_parse
 p11_kit_uri_free
index db694a7361480cf0b4344b57c5ba6c9d023bfdfd..931c1351e2614686e874d6bcf8de4fda93f12f9b 100644 (file)
@@ -1506,6 +1506,45 @@ test_uri_module_name_and_path (void)
        p11_kit_uri_free (uri);
 }
 
+static void
+test_uri_vendor_query (void)
+{
+       P11KitUri *uri;
+       const char *value;
+       char *string;
+       int ret;
+
+       uri = p11_kit_uri_new ();
+       assert_ptr_not_null (uri);
+
+       ret = p11_kit_uri_set_vendor_query (uri, "my-query-one", "123456");
+       assert_num_eq (1, ret);
+       value = p11_kit_uri_get_vendor_query (uri, "my-query-one");
+       assert_str_eq ("123456", value);
+
+       ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+       assert_num_eq (P11_KIT_URI_OK, ret);
+       assert (strstr (string, "my-query-one=123456") != NULL);
+       free (string);
+
+       ret = p11_kit_uri_parse ("pkcs11:?my-query-two=some-value", P11_KIT_URI_FOR_ANY, uri);
+       assert_num_eq (P11_KIT_URI_OK, ret);
+
+       value = p11_kit_uri_get_vendor_query (uri, "my-query-two");
+       assert_str_eq ("some-value", value);
+
+       ret = p11_kit_uri_set_vendor_query (uri, "my-query-two", "other-value");
+       assert_num_eq (1, ret);
+
+       value = p11_kit_uri_get_vendor_query (uri, "my-query-two");
+       assert_str_eq ("other-value", value);
+
+       ret = p11_kit_uri_set_vendor_query (uri, "my-query-three", NULL);
+       assert_num_eq (0, ret);
+
+       p11_kit_uri_free (uri);
+}
+
 static void
 test_uri_slot_id (void)
 {
@@ -1618,6 +1657,7 @@ main (int argc,
        p11_test (test_uri_module_name_bad, "/uri/module-name-bad");
        p11_test (test_uri_module_path, "/uri/module-path");
        p11_test (test_uri_module_name_and_path, "/uri/module-name-and-path");
+       p11_test (test_uri_vendor_query, "/uri/vendor-query");
        p11_test (test_uri_slot_id, "/uri/slot-id");
        p11_test (test_uri_slot_id_bad, "/uri/slot-id-bad");
        p11_test (test_uri_free_null, "/uri/test_uri_free_null");
index 5a3e19e5a365b89b0f94bbc0421d8d95a4fabc4c..a61daef0ec5875105c8ccfb6924914105c5e8a3f 100644 (file)
@@ -38,6 +38,7 @@
 #include "buffer.h"
 #define P11_DEBUG_FLAG P11_DEBUG_URI
 #include "debug.h"
+#include "dict.h"
 #include "message.h"
 #include "pkcs11.h"
 #include "private.h"
@@ -150,6 +151,7 @@ struct p11_kit_uri {
        char *pin_value;
        char *module_name;
        char *module_path;
+       p11_dict *qattrs;
 };
 
 static char *
@@ -794,6 +796,49 @@ p11_kit_uri_set_module_path (P11KitUri *uri, const char *path)
        uri->module_path = path ? strdup (path) : NULL;
 }
 
+/**
+ * p11_kit_uri_get_vendor_query:
+ * @uri: The URI
+ * @name: The name of vendor query
+ *
+ * Get the vendor query part of the URI, identified by @name. This is
+ * used by some applications to explicitly specify the path of a
+ * PKCS\#11 module.
+ *
+ * Returns: The value of vendor query or %NULL if not present.
+ */
+const char*
+p11_kit_uri_get_vendor_query (P11KitUri *uri, const char *name)
+{
+       return_val_if_fail (uri != NULL, NULL);
+       return p11_dict_get (uri->qattrs, name);
+}
+
+/**
+ * p11_kit_uri_set_vendor_query:
+ * @uri: The URI
+ * @name: The name of vendor query
+ * @value: (allow-none): The value of vendor query
+ *
+ * Set the vendor query part of the URI, identified by @name. This is
+ * used by some applications to explicitly specify the path of a
+ * PKCS\#11 module.
+ *
+ * Returns: 1 if the vendor query is set or removed, 0 if not.
+ */
+int
+p11_kit_uri_set_vendor_query (P11KitUri *uri, const char *name,
+                             const char *value)
+{
+       return_val_if_fail (uri != NULL, 0);
+       return_val_if_fail (name != NULL, 0);
+
+       if (value == NULL)
+               return p11_dict_remove (uri->qattrs, name);
+
+       return p11_dict_set (uri->qattrs, strdup (name), strdup (value));
+}
+
 /**
  * p11_kit_uri_new:
  *
@@ -816,6 +861,7 @@ p11_kit_uri_new (void)
        uri->module.libraryVersion.major = (CK_BYTE)-1;
        uri->module.libraryVersion.minor = (CK_BYTE)-1;
        uri->slot_id = (CK_SLOT_ID)-1;
+       uri->qattrs = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free);
 
        return uri;
 }
@@ -1124,6 +1170,23 @@ p11_kit_uri_format (P11KitUri *uri, P11KitUriType uri_type, char **string)
                }
        }
 
+       if (uri->qattrs) {
+               p11_dictiter iter;
+               void *_key;
+               void *_value;
+
+               p11_dict_iterate (uri->qattrs, &iter);
+               while (p11_dict_next (&iter, &_key, &_value)) {
+                       char *key = _key;
+                       char *value = _value;
+                       if (!format_encode_string (&buffer, &sep, key,
+                                                  (const unsigned char *) value,
+                                                  strlen (value), 0)) {
+                               return_val_if_reached (P11_KIT_URI_UNEXPECTED);
+                       }
+               }
+       }
+
        return_val_if_fail (p11_buffer_ok (&buffer), P11_KIT_URI_UNEXPECTED);
        *string = p11_buffer_steal (&buffer, NULL);
        return P11_KIT_URI_OK;
@@ -1448,6 +1511,37 @@ parse_module_query (const char *name_start, const char *name_end,
        return 0;
 }
 
+static int
+parse_vendor_query (const char *name_start, const char *name_end,
+                   const char *start, const char *end,
+                   P11KitUri *uri)
+{
+       unsigned char *name;
+       unsigned char *value;
+
+       assert (name_start <= name_end);
+       assert (start <= end);
+
+       /* FIXME: Should we limit the characters in NAME, according to
+        * the specification?  */
+       name = malloc (name_end - name_start + 1);
+       if (name == NULL)
+               return P11_KIT_URI_BAD_ENCODING;
+       memcpy (name, name_start, name_end - name_start);
+       name[name_end - name_start] = '\0';
+
+       value = p11_url_decode (start, end, P11_URL_WHITESPACE, NULL);
+       if (value == NULL) {
+               free (name);
+               return P11_KIT_URI_BAD_ENCODING;
+       }
+
+       if (!p11_dict_set (uri->qattrs, name, value))
+               return 1;
+
+       return 0;
+}
+
 /**
  * p11_kit_uri_parse:
  * @string: The string to parse
@@ -1523,6 +1617,7 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type,
        uri->module_name = NULL;
        free (uri->module_path);
        uri->module_path = NULL;
+       p11_dict_clear (uri->qattrs);
 
        /* Parse the path. */
        for (;;) {
@@ -1593,12 +1688,12 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type,
                ret = parse_pin_query (string, epos, epos + 1, spos, uri);
                if (ret == 0)
                        ret = parse_module_query (string, epos, epos + 1, spos, uri);
+               if (ret == 0)
+                       ret = parse_vendor_query (string, epos, epos + 1, spos, uri);
                if (ret < 0) {
                        free (allocated);
                        return ret;
                }
-               if (ret == 0)
-                       uri->unrecognized = true;
 
                string = spos;
        }
@@ -1624,6 +1719,7 @@ p11_kit_uri_free (P11KitUri *uri)
        free (uri->pin_value);
        free (uri->module_name);
        free (uri->module_path);
+       p11_dict_free (uri->qattrs);
        free (uri);
 }
 
index e4d333019fadd9f88b372708957c7889dd9c3cd1..0982737d0936cdaf4acd33b7fb5ae847f5282798 100644 (file)
@@ -163,6 +163,12 @@ const char*         p11_kit_uri_get_module_path             (P11KitUri *uri);
 void                p11_kit_uri_set_module_path             (P11KitUri *uri,
                                                              const char *path);
 
+const char*         p11_kit_uri_get_vendor_query            (P11KitUri *uri,
+                                                            const char *name);
+int                 p11_kit_uri_set_vendor_query            (P11KitUri *uri,
+                                                            const char *name,
+                                                            const char *value);
+
 void                p11_kit_uri_set_unrecognized            (P11KitUri *uri,
                                                              int unrecognized);