summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-08-19 10:31:51 +0200
committerStef Walter <stefw@collabora.co.uk>2011-08-19 10:31:51 +0200
commitae95625311e98caa3cccf82d24a3b612df11b26d (patch)
tree7ed56ccc0be88540c2bb7ccba74731b00e920891
parentd4abb441450deceff760086dcdf9d493b258074a (diff)
downloadp11-kit-ae95625311e98caa3cccf82d24a3b612df11b26d.tar.gz
Ignore spaces in PKCS#11 URIs
* These should be able to occur anywhere and should be ignored according to RFC 3986. This is documented in the PKCS#11 URI specification.
-rw-r--r--p11-kit/uri.c85
-rw-r--r--p11-kit/uri.h4
-rw-r--r--tests/uri-test.c24
3 files changed, 90 insertions, 23 deletions
diff --git a/p11-kit/uri.c b/p11-kit/uri.c
index d466486..bd057d5 100644
--- a/p11-kit/uri.c
+++ b/p11-kit/uri.c
@@ -147,6 +147,7 @@ struct p11_kit_uri {
};
const static char HEX_CHARS[] = "0123456789abcdef";
+const static char WHITESPACE[] = " \n\r\v";
static int
url_decode (const char *value, const char *end,
@@ -185,6 +186,12 @@ url_decode (const char *value, const char *end,
*p = (a - HEX_CHARS) << 4;
*(p++) |= (b - HEX_CHARS);
value += 2;
+
+ /* Ignore whitespace characters */
+ } else if (strchr (WHITESPACE, *value)) {
+ value++;
+
+ /* A different character */
} else {
*(p++) = *(value++);
}
@@ -235,6 +242,32 @@ url_encode (const unsigned char *value, const unsigned char *end, size_t *length
return result;
}
+static char *
+key_decode (const char *value, const char *end)
+{
+ size_t length = (end - value);
+ char *at, *pos;
+ char *key;
+
+ key = malloc (length + 1);
+ if (key == NULL)
+ return NULL;
+
+ memcpy (key, value, length);
+ key[length] = '\0';
+
+ /* Do we have any whitespace? Strip it out. */
+ if (strcspn (key, WHITESPACE) != length) {
+ for (at = key, pos = key; pos != key + length + 1; ++pos) {
+ if (!strchr (WHITESPACE, *pos))
+ *(at++) = *pos;
+ }
+ *at = '\0';
+ }
+
+ return key;
+}
+
static int
match_struct_string (const unsigned char *inuri, const unsigned char *real,
size_t length)
@@ -918,7 +951,8 @@ p11_kit_uri_format (P11KitUri *uri, P11KitUriType uri_type, char **string)
length = P11_KIT_URI_SCHEME_LEN;
memcpy (result, P11_KIT_URI_SCHEME, length);
- result[length] = 0;
+ result[length] = ':';
+ result[++length] = 0;
if ((uri_type & P11_KIT_URI_FOR_MODULE) == P11_KIT_URI_FOR_MODULE) {
if (!format_struct_string (&result, &length, &is_first, "library-description",
@@ -1013,19 +1047,12 @@ parse_string_attribute (const char *name, const char *start, const char *end,
}
static int
-equals_segment (const char *start, const char *end, const char *match)
-{
- size_t len = strlen (match);
- assert (start <= end);
- return (end - start == len) && memcmp (start, match, len) == 0;
-}
-
-static int
parse_class_attribute (const char *name, const char *start, const char *end,
P11KitUri *uri)
{
CK_OBJECT_CLASS klass = 0;
CK_ATTRIBUTE attr;
+ char *value;
assert (start <= end);
@@ -1033,23 +1060,29 @@ parse_class_attribute (const char *name, const char *start, const char *end,
strcmp ("object-type", name) != 0)
return 0;
- if (equals_segment (start, end, "cert"))
+ value = key_decode (start, end);
+ if (value == NULL)
+ return P11_KIT_URI_NO_MEMORY;
+ if (strcmp (value, "cert") == 0)
klass = CKO_CERTIFICATE;
- else if (equals_segment (start, end, "public"))
+ else if (strcmp (value, "public") == 0)
klass = CKO_PUBLIC_KEY;
- else if (equals_segment (start, end, "private"))
+ else if (strcmp (value, "private") == 0)
klass = CKO_PRIVATE_KEY;
- else if (equals_segment (start, end, "secretkey"))
+ else if (strcmp (value, "secretkey") == 0)
klass = CKO_SECRET_KEY;
- else if (equals_segment (start, end, "secret-key"))
+ else if (strcmp (value, "secret-key") == 0)
klass = CKO_SECRET_KEY;
- else if (equals_segment (start, end, "data"))
+ else if (strcmp (value, "data") == 0)
klass = CKO_DATA;
else {
+ free (value);
uri->unrecognized = 1;
return 1;
}
+ free (value);
+
attr.pValue = malloc (sizeof (klass));
if (attr.pValue == NULL)
return P11_KIT_URI_NO_MEMORY;
@@ -1123,6 +1156,10 @@ atoin (const char *start, const char *end)
{
int ret = 0;
while (start != end) {
+ if (strchr (WHITESPACE, *start)) {
+ start++;
+ continue;
+ }
if (*start < '0' || *start > '9')
return -1;
ret *= 10;
@@ -1252,16 +1289,24 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type,
{
const char *spos, *epos;
char *key = NULL;
- int ret = -1;
+ int ret;
int i;
assert (string);
assert (uri);
- if (strncmp (string, P11_KIT_URI_SCHEME, P11_KIT_URI_SCHEME_LEN) != 0)
+ epos = strchr (string, ':');
+ if (epos == NULL)
+ return P11_KIT_URI_BAD_SCHEME;
+ key = key_decode (string, epos);
+ ret = strcmp (key, P11_KIT_URI_SCHEME);
+ free (key);
+
+ if (ret != 0)
return P11_KIT_URI_BAD_SCHEME;
- string += P11_KIT_URI_SCHEME_LEN;
+ string = epos + 1;
+ ret = -1;
/* Clear everything out */
memset (&uri->module, 0, sizeof (uri->module));
@@ -1290,11 +1335,9 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type,
if (epos == NULL || spos == string || epos == string || epos >= spos)
return P11_KIT_URI_BAD_SYNTAX;
- key = malloc ((epos - string) + 1);
+ key = key_decode (string, epos);
if (key == NULL)
return P11_KIT_URI_NO_MEMORY;
- memcpy (key, string, epos - string);
- key[epos - string] = 0;
epos++;
ret = 0;
diff --git a/p11-kit/uri.h b/p11-kit/uri.h
index e08dfc8..98a233d 100644
--- a/p11-kit/uri.h
+++ b/p11-kit/uri.h
@@ -41,8 +41,8 @@
extern "C" {
#endif
-#define P11_KIT_URI_SCHEME "pkcs11:"
-#define P11_KIT_URI_SCHEME_LEN 7
+#define P11_KIT_URI_SCHEME "pkcs11"
+#define P11_KIT_URI_SCHEME_LEN 6
typedef enum {
P11_KIT_URI_OK = 0,
diff --git a/tests/uri-test.c b/tests/uri-test.c
index 8ab8f93..0e8c718 100644
--- a/tests/uri-test.c
+++ b/tests/uri-test.c
@@ -275,6 +275,29 @@ test_uri_parse_with_bad_syntax (CuTest *tc)
}
static void
+test_uri_parse_with_spaces (CuTest *tc)
+{
+ P11KitUri *uri = NULL;
+ CK_INFO_PTR info;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkc\ns11: lib rary-desc\rrip \n tion =The%20Library;\n\n\nlibrary-manufacturer=\rMe",
+ P11_KIT_URI_FOR_MODULE, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ info = p11_kit_uri_get_module_info (uri);
+
+ CuAssertTrue (tc, is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me"));
+ CuAssertTrue (tc, is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library"));
+
+ p11_kit_uri_free (uri);
+}
+
+
+static void
test_uri_parse_with_library (CuTest *tc)
{
P11KitUri *uri = NULL;
@@ -1146,6 +1169,7 @@ main (void)
SUITE_ADD_TEST (suite, test_uri_parse_with_token);
SUITE_ADD_TEST (suite, test_uri_parse_with_token_bad_encoding);
SUITE_ADD_TEST (suite, test_uri_parse_with_bad_syntax);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_spaces);
SUITE_ADD_TEST (suite, test_uri_parse_with_library);
SUITE_ADD_TEST (suite, test_uri_parse_with_library_bad_encoding);
SUITE_ADD_TEST (suite, test_uri_build_empty);