diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-08-19 10:31:51 +0200 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-08-19 10:31:51 +0200 |
commit | ae95625311e98caa3cccf82d24a3b612df11b26d (patch) | |
tree | 7ed56ccc0be88540c2bb7ccba74731b00e920891 | |
parent | d4abb441450deceff760086dcdf9d493b258074a (diff) |
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.c | 85 | ||||
-rw-r--r-- | p11-kit/uri.h | 4 | ||||
-rw-r--r-- | tests/uri-test.c | 24 |
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); |