]> granicus.if.org Git - p11-kit/commitdiff
Ignore spaces in PKCS#11 URIs
authorStef Walter <stefw@collabora.co.uk>
Fri, 19 Aug 2011 08:31:51 +0000 (10:31 +0200)
committerStef Walter <stefw@collabora.co.uk>
Fri, 19 Aug 2011 08:31:51 +0000 (10:31 +0200)
 * These should be able to occur anywhere and should be ignored
   according to RFC 3986. This is documented in the PKCS#11 URI
   specification.

p11-kit/uri.c
p11-kit/uri.h
tests/uri-test.c

index d466486ed77835be5fb5960970e9243734bd886e..bd057d548665b83172c460a533f704a8bfedd5e9 100644 (file)
@@ -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",
@@ -1012,20 +1046,13 @@ parse_string_attribute (const char *name, const char *start, const char *end,
        return 1;
 }
 
-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;
index e08dfc81ceb4ba96f55dbc1a97ed81e8b15e5959..98a233d7b93ee6d8b612d248fbb88948277b7d81 100644 (file)
@@ -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,
index 8ab8f93b465fc4ad09a1bde19522fe62f2980712..0e8c7181c17517172693b69b9dff0a97a41a8103 100644 (file)
@@ -274,6 +274,29 @@ test_uri_parse_with_bad_syntax (CuTest *tc)
        p11_kit_uri_free (uri);
 }
 
+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)
 {
@@ -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);