diff options
author | Stef Walter <stefw@gnome.org> | 2013-01-07 11:12:29 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2013-01-09 13:49:44 +0100 |
commit | 3ebc9a78d4bca0b630a8b887ab93d6cc654f2cb2 (patch) | |
tree | 03c91a439c775d400054343b4157c3720c1dd3fc | |
parent | 4a0bd25fcafae57ef2ae0cfe8676eee2332d5951 (diff) |
Add common functions for manipulating CK_ATTRIBUTE arrays
-rw-r--r-- | common/Makefile.am | 1 | ||||
-rw-r--r-- | common/attrs.c | 310 | ||||
-rw-r--r-- | common/attrs.h | 86 | ||||
-rw-r--r-- | common/tests/Makefile.am | 1 | ||||
-rw-r--r-- | common/tests/test-attrs.c | 518 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | p11-kit/tests/uri-test.c | 6 | ||||
-rw-r--r-- | p11-kit/uri.c | 207 |
8 files changed, 977 insertions, 154 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index c23e6d9..5d38c88 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -18,6 +18,7 @@ libp11_compat_la_SOURCES = \ $(NULL) libp11_library_la_SOURCES = \ + attrs.c attrs.h \ array.c array.h \ debug.c debug.h \ dict.c dict.h \ diff --git a/common/attrs.c b/common/attrs.c new file mode 100644 index 0000000..2f4dca7 --- /dev/null +++ b/common/attrs.c @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2012, Redhat Inc. + * Copyright (c) 2011, Collabora Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter <stefw@collabora.co.uk> + */ + +#include "config.h" + +#include "attrs.h" +#include "compat.h" +#include "debug.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +CK_BBOOL +p11_attrs_is_empty (CK_ATTRIBUTE *attrs) +{ + return (attrs == NULL || attrs->type == CKA_INVALID); +} + +CK_ULONG +p11_attrs_count (CK_ATTRIBUTE *attrs) +{ + CK_ULONG count; + + if (attrs == NULL) + return 0; + + for (count = 0; !p11_attrs_is_empty (attrs); count++, attrs++); + + return count; +} + +void +p11_attrs_free (void *attrs) +{ + CK_ATTRIBUTE *ats = attrs; + int i; + + if (!attrs) + return; + + for (i = 0; !p11_attrs_is_empty (ats + i); i++) + free (ats[i].pValue); + free (ats); +} + +static CK_ATTRIBUTE * +attrs_build (CK_ATTRIBUTE *attrs, + CK_ULONG count_to_add, + int copy, + CK_ATTRIBUTE * (*generator) (void *), + void *state) +{ + CK_ATTRIBUTE *attr; + CK_ATTRIBUTE *add; + CK_ULONG current; + CK_ULONG at; + CK_ULONG j; + CK_ULONG i; + + /* How many attributes we already have */ + current = p11_attrs_count (attrs); + + /* Reallocate for how many we need */ + attrs = realloc (attrs, (current + count_to_add + 1) * sizeof (CK_ATTRIBUTE)); + return_val_if_fail (attrs != NULL, NULL); + + at = current; + for (i = 0; i < count_to_add; i++) { + add = (generator) (state); + + /* Skip with invalid type */ + if (!add || add->type == CKA_INVALID) + continue; + + attr = NULL; + + /* Do we have this attribute? */ + for (j = 0; attr == NULL && j < current; j++) { + if (attrs[j].type == add->type) { + attr = attrs + j; + free (attrs[j].pValue); + break; + } + } + + if (attr == NULL) { + attr = attrs + at; + at++; + } + + memcpy (attr, add, sizeof (CK_ATTRIBUTE)); + if (copy) + attr->pValue = memdup (attr->pValue, attr->ulValueLen); + } + + /* Mark this as the end */ + (attrs + at)->type = CKA_INVALID; + assert (p11_attrs_is_empty (attrs + at)); + return attrs; +} + +static CK_ATTRIBUTE * +vararg_generator (void *state) +{ + va_list *va = state; + return va_arg (*va, CK_ATTRIBUTE *); +} + +CK_ATTRIBUTE * +p11_attrs_build (CK_ATTRIBUTE *attrs, + ...) +{ + CK_ULONG count; + va_list va; + + count = 0; + va_start (va, attrs); + while (va_arg (va, CK_ATTRIBUTE *)) + count++; + va_end (va); + + va_start (va, attrs); + attrs = attrs_build (attrs, count, 1, vararg_generator, va); + va_end (va); + + return attrs; +} + +static CK_ATTRIBUTE * +template_generator (void *state) +{ + CK_ATTRIBUTE **template = state; + return (*template)++; +} + +CK_ATTRIBUTE * +p11_attrs_buildn (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *add, + CK_ULONG count) +{ + return attrs_build (attrs, count, 1, template_generator, &add); +} + +CK_ATTRIBUTE * +p11_attrs_take (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type, + CK_VOID_PTR value, + CK_ULONG length) +{ + CK_ATTRIBUTE attr = { type, value, length }; + CK_ATTRIBUTE *add = &attr; + return attrs_build (attrs, 1, 0, template_generator, &add); +} + +CK_ATTRIBUTE * +p11_attrs_dup (CK_ATTRIBUTE *attrs) +{ + CK_ULONG count; + + count = p11_attrs_count (attrs); + return p11_attrs_buildn (NULL, attrs, count); +} + +CK_ATTRIBUTE * +p11_attrs_find (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type) +{ + CK_ULONG i; + + for (i = 0; !p11_attrs_is_empty (attrs + i); i++) { + if (attrs[i].type == type) + return attrs + i; + } + + return NULL; +} + +CK_ATTRIBUTE * +p11_attrs_findn (CK_ATTRIBUTE *attrs, + CK_ULONG count, + CK_ATTRIBUTE_TYPE type) +{ + CK_ULONG i; + + for (i = 0; i < count; i++) { + if (attrs[i].type == type) + return attrs + i; + } + + return NULL; +} + +CK_BBOOL +p11_attrs_remove (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type) +{ + CK_ULONG count; + CK_ULONG i; + + count = p11_attrs_count (attrs); + for (i = 0; i < count; i++) { + if (attrs[i].type == type) + break; + } + + if (i == count) + return CK_FALSE; + + if (attrs[i].pValue) + free (attrs[i].pValue); + + memmove (attrs + i, attrs + i + 1, (count - (i + 1)) * sizeof (CK_ATTRIBUTE)); + attrs[count - 1].type = CKA_INVALID; + return CK_TRUE; +} + +CK_BBOOL +p11_attrs_match (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *match) +{ + CK_ATTRIBUTE *attr; + + for (; !p11_attrs_is_empty (match); match++) { + attr = p11_attrs_find (attrs, match->type); + if (!attr) + return CK_FALSE; + if (!p11_attr_equal (attr, match)) + return CK_FALSE; + } + + return CK_TRUE; +} + +CK_BBOOL +p11_attrs_matchn (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *match, + CK_ULONG count) +{ + CK_ATTRIBUTE *attr; + CK_ULONG i; + + for (i = 0; i < count; i++) { + attr = p11_attrs_find (attrs, match[i].type); + if (!attr) + return CK_FALSE; + if (!p11_attr_equal (attr, match + i)) + return CK_FALSE; + } + + return CK_TRUE; + +} + +CK_BBOOL +p11_attr_match_boolean (CK_ATTRIBUTE *attr, + CK_BBOOL value) +{ + return (attr->ulValueLen == sizeof (value) && + attr->pValue != NULL && + memcmp (attr->pValue, &value, sizeof (value)) == 0); +} + +CK_BBOOL +p11_attr_equal (CK_ATTRIBUTE *one, + CK_ATTRIBUTE *two) +{ + if (one == two) + return CK_TRUE; + if (!one || !two || one->type != two->type || one->ulValueLen != two->ulValueLen) + return CK_FALSE; + if (one->pValue == two->pValue) + return TRUE; + if (!one->pValue || !two->pValue) + return FALSE; + return memcmp (one->pValue, two->pValue, one->ulValueLen) == 0; +} diff --git a/common/attrs.h b/common/attrs.h new file mode 100644 index 0000000..12a2798 --- /dev/null +++ b/common/attrs.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012, Redhat Inc. + * Copyright (c) 2011, Collabora Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter <stefw@collabora.co.uk> + */ + +#ifndef P11_ATTRS_H_ +#define P11_ATTRS_H_ + +#include "pkcs11.h" + +#define CKA_INVALID ((CK_ULONG)-1) + +CK_ATTRIBUTE * p11_attrs_dup (CK_ATTRIBUTE *attrs); + +CK_ATTRIBUTE * p11_attrs_build (CK_ATTRIBUTE *attrs, + ...); + +CK_ATTRIBUTE * p11_attrs_buildn (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *add, + CK_ULONG count); + +CK_ATTRIBUTE * p11_attrs_take (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type, + CK_VOID_PTR value, + CK_ULONG length); + +CK_BBOOL p11_attrs_is_empty (CK_ATTRIBUTE *attrs); + +CK_ULONG p11_attrs_count (CK_ATTRIBUTE *attrs); + +void p11_attrs_free (void *attrs); + +CK_ATTRIBUTE * p11_attrs_find (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type); + +CK_ATTRIBUTE * p11_attrs_findn (CK_ATTRIBUTE *attrs, + CK_ULONG count, + CK_ATTRIBUTE_TYPE type); + +CK_BBOOL p11_attrs_remove (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE_TYPE type); + +CK_BBOOL p11_attrs_match (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *match); + +CK_BBOOL p11_attrs_matchn (CK_ATTRIBUTE *attrs, + CK_ATTRIBUTE *match, + CK_ULONG count); + +CK_BBOOL p11_attr_equal (CK_ATTRIBUTE *one, + CK_ATTRIBUTE *two); + +CK_BBOOL p11_attr_match_boolean (CK_ATTRIBUTE *attr, + CK_BBOOL value); + +#endif /* P11_ATTRS_H_ */ diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am index af61786..4badbb5 100644 --- a/common/tests/Makefile.am +++ b/common/tests/Makefile.am @@ -20,6 +20,7 @@ LDADD = \ CHECK_PROGS = \ test-dict \ test-array \ + test-attrs \ $(NULL) noinst_PROGRAMS = \ diff --git a/common/tests/test-attrs.c b/common/tests/test-attrs.c new file mode 100644 index 0000000..e358edf --- /dev/null +++ b/common/tests/test-attrs.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2012 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter <stefw@gnome.org> + */ + +#include "config.h" +#include "CuTest.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "attrs.h" + +static void +test_count (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + + CK_ATTRIBUTE attrs[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE empty[] = { + { CKA_INVALID }, + }; + + CuAssertIntEquals (tc, 2, p11_attrs_count (attrs)); + CuAssertIntEquals (tc, 0, p11_attrs_count (NULL)); + CuAssertIntEquals (tc, 0, p11_attrs_count (empty)); +} + +static void +test_build_one (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE add = { CKA_LABEL, "yay", 3 }; + + attrs = p11_attrs_build (NULL, &add, NULL); + + /* Test the first attribute */ + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs->type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs->ulValueLen); + CuAssertTrue (tc, memcmp (attrs->pValue, "yay", 3) == 0); + + CuAssertTrue (tc, attrs[1].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_build_two (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 }; + CK_ATTRIBUTE two = { CKA_VALUE, "eight", 5 }; + + attrs = p11_attrs_build (NULL, &one, &two, NULL); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[0].type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs[0].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[0].pValue, "yay", 3) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 5, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "eight", 5) == 0); + + CuAssertTrue (tc, attrs[2].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_build_invalid (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 }; + CK_ATTRIBUTE invalid = { CKA_INVALID }; + CK_ATTRIBUTE two = { CKA_VALUE, "eight", 5 }; + + attrs = p11_attrs_build (NULL, &one, &invalid, &two, NULL); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[0].type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs[0].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[0].pValue, "yay", 3) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 5, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "eight", 5) == 0); + + CuAssertTrue (tc, attrs[2].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_buildn_two (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE add[] = { + { CKA_LABEL, "yay", 3 }, + { CKA_VALUE, "eight", 5 } + }; + + attrs = p11_attrs_buildn (NULL, add, 2); + + /* Test the first attribute */ + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs->type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs->ulValueLen); + CuAssertTrue (tc, memcmp (attrs->pValue, "yay", 3) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 5, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "eight", 5) == 0); + + CuAssertTrue (tc, attrs[2].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_buildn_one (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE add = { CKA_LABEL, "yay", 3 }; + + attrs = p11_attrs_buildn (NULL, &add, 1); + + /* Test the first attribute */ + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs->type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs->ulValueLen); + CuAssertTrue (tc, memcmp (attrs->pValue, "yay", 3) == 0); + + CuAssertTrue (tc, attrs[1].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_build_add (CuTest *tc) +{ + CK_ATTRIBUTE initial[] = { + { CKA_LABEL, "label", 5 }, + { CKA_VALUE, "nine", 4 }, + }; + + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 }; + CK_ATTRIBUTE two = { CKA_TOKEN, "\x01", 1 }; + + attrs = p11_attrs_buildn (NULL, initial, 2); + attrs = p11_attrs_build (attrs, &one, &two, NULL); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[0].type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs[0].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[0].pValue, "yay", 3) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 4, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "nine", 4) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[2].type == CKA_TOKEN); + CuAssertIntEquals (tc, 1, attrs[2].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[2].pValue, "\x01", 1) == 0); + + CuAssertTrue (tc, attrs[3].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_build_null (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE add = { CKA_LABEL, NULL, (CK_ULONG)-1 }; + + attrs = p11_attrs_build (NULL, &add, NULL); + + /* Test the first attribute */ + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs->type == CKA_LABEL); + CuAssertTrue (tc, attrs->ulValueLen == (CK_ULONG)-1); + CuAssertPtrEquals (tc, NULL, attrs->pValue); + + p11_attrs_free (attrs); +} + +static void +test_dup (CuTest *tc) +{ + CK_ATTRIBUTE *attrs; + CK_ATTRIBUTE original[] = { + { CKA_LABEL, "yay", 3 }, + { CKA_VALUE, "eight", 5 }, + { CKA_INVALID } + }; + + attrs = p11_attrs_dup (original); + + /* Test the first attribute */ + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs->type == CKA_LABEL); + CuAssertIntEquals (tc, 3, attrs->ulValueLen); + CuAssertTrue (tc, memcmp (attrs->pValue, "yay", 3) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 5, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "eight", 5) == 0); + + CuAssertTrue (tc, attrs[2].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_take (CuTest *tc) +{ + CK_ATTRIBUTE initial[] = { + { CKA_LABEL, "label", 5 }, + { CKA_VALUE, "nine", 4 }, + }; + + CK_ATTRIBUTE *attrs; + + attrs = p11_attrs_buildn (NULL, initial, 2); + attrs = p11_attrs_take (attrs, CKA_LABEL, strdup ("boooyah"), 7); + attrs = p11_attrs_take (attrs, CKA_TOKEN, strdup ("\x01"), 1); + CuAssertPtrNotNull (tc, attrs); + + CuAssertTrue (tc, attrs[0].type == CKA_LABEL); + CuAssertIntEquals (tc, 7, attrs[0].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[0].pValue, "boooyah", 7) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[1].type == CKA_VALUE); + CuAssertIntEquals (tc, 4, attrs[1].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[1].pValue, "nine", 4) == 0); + + CuAssertPtrNotNull (tc, attrs); + CuAssertTrue (tc, attrs[2].type == CKA_TOKEN); + CuAssertIntEquals (tc, 1, attrs[2].ulValueLen); + CuAssertTrue (tc, memcmp (attrs[2].pValue, "\x01", 1) == 0); + + CuAssertTrue (tc, attrs[3].type == CKA_INVALID); + + p11_attrs_free (attrs); +} + +static void +test_free_null (CuTest *tc) +{ + p11_attrs_free (NULL); +} + +static void +test_equal (CuTest *tc) +{ + char *data = "extra attribute"; + CK_ATTRIBUTE one = { CKA_LABEL, "yay", 3 }; + CK_ATTRIBUTE null = { CKA_LABEL, NULL, 3 }; + CK_ATTRIBUTE two = { CKA_VALUE, "yay", 3 }; + CK_ATTRIBUTE other = { CKA_VALUE, data, 5 }; + CK_ATTRIBUTE overflow = { CKA_VALUE, data, 5 }; + CK_ATTRIBUTE content = { CKA_VALUE, "conte", 5 }; + + CuAssertTrue (tc, p11_attr_equal (&one, &one)); + CuAssertTrue (tc, !p11_attr_equal (&one, NULL)); + CuAssertTrue (tc, !p11_attr_equal (NULL, &one)); + CuAssertTrue (tc, !p11_attr_equal (&one, &two)); + CuAssertTrue (tc, !p11_attr_equal (&two, &other)); + CuAssertTrue (tc, p11_attr_equal (&other, &overflow)); + CuAssertTrue (tc, !p11_attr_equal (&one, &null)); + CuAssertTrue (tc, !p11_attr_equal (&one, &null)); + CuAssertTrue (tc, !p11_attr_equal (&other, &content)); +} + +static void +test_find (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + CK_ATTRIBUTE *attr; + + CK_ATTRIBUTE attrs[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID }, + }; + + attr = p11_attrs_find (attrs, CKA_LABEL); + CuAssertPtrEquals (tc, attrs + 0, attr); + + attr = p11_attrs_find (attrs, CKA_TOKEN); + CuAssertPtrEquals (tc, attrs + 1, attr); + + attr = p11_attrs_find (attrs, CKA_VALUE); + CuAssertPtrEquals (tc, NULL, attr); +} + +static void +test_findn (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + CK_ATTRIBUTE *attr; + + CK_ATTRIBUTE attrs[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + }; + + attr = p11_attrs_findn (attrs, 2, CKA_LABEL); + CuAssertPtrEquals (tc, attrs + 0, attr); + + attr = p11_attrs_findn (attrs, 2, CKA_TOKEN); + CuAssertPtrEquals (tc, attrs + 1, attr); + + attr = p11_attrs_findn (attrs, 2, CKA_VALUE); + CuAssertPtrEquals (tc, NULL, attr); + + attr = p11_attrs_findn (attrs, 1, CKA_TOKEN); + CuAssertPtrEquals (tc, NULL, attr); +} + +static void +test_remove (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + CK_ATTRIBUTE *attr; + CK_ATTRIBUTE *attrs; + CK_BBOOL ret; + + CK_ATTRIBUTE initial[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + }; + + attrs = p11_attrs_buildn (NULL, initial, 2); + CuAssertPtrNotNull (tc, attrs); + + attr = p11_attrs_find (attrs, CKA_LABEL); + CuAssertPtrEquals (tc, attrs + 0, attr); + + ret = p11_attrs_remove (attrs, CKA_LABEL); + CuAssertIntEquals (tc, CK_TRUE, ret); + + attr = p11_attrs_find (attrs, CKA_LABEL); + CuAssertPtrEquals (tc, NULL, attr); + + ret = p11_attrs_remove (attrs, CKA_LABEL); + CuAssertIntEquals (tc, CK_FALSE, ret); + + p11_attrs_free (attrs); +} + +static void +test_match (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + + CK_ATTRIBUTE attrs[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE subset[] = { + { CKA_LABEL, "label", 5 }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE different[] = { + { CKA_LABEL, "other", 5 }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE extra[] = { + { CKA_VALUE, "the value", 9 }, + { CKA_LABEL, "other", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID }, + }; + + CuAssertTrue (tc, p11_attrs_match (attrs, attrs)); + CuAssertTrue (tc, p11_attrs_match (attrs, subset)); + CuAssertTrue (tc, !p11_attrs_match (attrs, different)); + CuAssertTrue (tc, !p11_attrs_match (attrs, extra)); +} + +static void +test_matchn (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + + CK_ATTRIBUTE attrs[] = { + { CKA_LABEL, "label", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE subset[] = { + { CKA_LABEL, "label", 5 }, + }; + + CK_ATTRIBUTE different[] = { + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_LABEL, "other", 5 }, + }; + + CK_ATTRIBUTE extra[] = { + { CKA_VALUE, "the value", 9 }, + { CKA_LABEL, "other", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + }; + + CuAssertTrue (tc, p11_attrs_matchn (attrs, subset, 1)); + CuAssertTrue (tc, !p11_attrs_matchn (attrs, different, 2)); + CuAssertTrue (tc, !p11_attrs_matchn (attrs, extra, 3)); +} + +static void +test_match_boolean (CuTest *tc) +{ + CK_BBOOL vtrue = CK_TRUE; + CK_BBOOL vfalse = CK_FALSE; + CK_ATTRIBUTE one = { CKA_LABEL, "\x01yy", 3 }; + CK_ATTRIBUTE two = { CKA_LABEL, "\x00yy", 3 }; + CK_ATTRIBUTE atrue = { CKA_TOKEN, &vtrue, sizeof (CK_BBOOL) }; + CK_ATTRIBUTE afalse = { CKA_TOKEN, &vfalse, sizeof (CK_BBOOL) }; + + CuAssertTrue (tc, p11_attr_match_boolean (&atrue, CK_TRUE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&atrue, CK_FALSE)); + CuAssertTrue (tc, p11_attr_match_boolean (&afalse, CK_FALSE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&afalse, CK_TRUE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&one, CK_TRUE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&one, CK_FALSE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&two, CK_FALSE)); + CuAssertTrue (tc, !p11_attr_match_boolean (&two, CK_TRUE)); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + SUITE_ADD_TEST (suite, test_count); + SUITE_ADD_TEST (suite, test_build_one); + SUITE_ADD_TEST (suite, test_build_two); + SUITE_ADD_TEST (suite, test_build_invalid); + SUITE_ADD_TEST (suite, test_buildn_one); + SUITE_ADD_TEST (suite, test_buildn_two); + SUITE_ADD_TEST (suite, test_build_add); + SUITE_ADD_TEST (suite, test_build_null); + SUITE_ADD_TEST (suite, test_dup); + SUITE_ADD_TEST (suite, test_take); + SUITE_ADD_TEST (suite, test_free_null); + SUITE_ADD_TEST (suite, test_match); + SUITE_ADD_TEST (suite, test_matchn); + SUITE_ADD_TEST (suite, test_find); + SUITE_ADD_TEST (suite, test_findn); + SUITE_ADD_TEST (suite, test_remove); + + SUITE_ADD_TEST (suite, test_match_boolean); + SUITE_ADD_TEST (suite, test_equal); + + CuSuiteRun (suite); + CuSuiteSummary (suite, output); + CuSuiteDetails (suite, output); + printf ("%s\n", output->buffer); + ret = suite->failCount; + CuSuiteDelete (suite); + CuStringDelete (output); + + return ret; +} diff --git a/configure.ac b/configure.ac index bb72391..a4d2857 100644 --- a/configure.ac +++ b/configure.ac @@ -69,7 +69,7 @@ if test "$os_unix" = "yes"; then [AC_MSG_ERROR([could not find nanosleep])]) AC_CHECK_MEMBERS([struct dirent.d_type],,,[#include <dirent.h>]) AC_CHECK_HEADERS([err.h errno.h]) - AC_CHECK_FUNCS([getprogname getexecname]) + AC_CHECK_FUNCS([getprogname getexecname memdup]) # Check if these are declared and/or available to link against AC_CHECK_DECLS([program_invocation_short_name]) diff --git a/p11-kit/tests/uri-test.c b/p11-kit/tests/uri-test.c index 0e3e722..ba4c634 100644 --- a/p11-kit/tests/uri-test.c +++ b/p11-kit/tests/uri-test.c @@ -993,12 +993,14 @@ test_uri_get_set_attribute (CuTest *tc) ret = p11_kit_uri_set_attribute (uri, &attr); CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + /* We can set other attributes */ attr.type = CKA_COLOR; ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_NOT_FOUND, ret); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + /* And get them too */ ptr = p11_kit_uri_get_attribute (uri, CKA_COLOR); - CuAssertPtrEquals (tc, NULL, ptr); + CuAssertPtrNotNull (tc, ptr); ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); CuAssertPtrNotNull (tc, ptr); diff --git a/p11-kit/uri.c b/p11-kit/uri.c index 1306fed..8828188 100644 --- a/p11-kit/uri.c +++ b/p11-kit/uri.c @@ -34,6 +34,7 @@ #include "config.h" +#include "attrs.h" #define P11_DEBUG_FLAG P11_DEBUG_URI #include "debug.h" #include "library.h" @@ -134,21 +135,11 @@ * Length of %P11_KIT_URI_SCHEME. */ -static const CK_ATTRIBUTE_TYPE SUPPORTED_ATTRIBUTE_TYPES[] = { - CKA_CLASS, - CKA_LABEL, - CKA_ID -}; - -#define NUM_ATTRIBUTE_TYPES \ - (sizeof (SUPPORTED_ATTRIBUTE_TYPES) / sizeof (SUPPORTED_ATTRIBUTE_TYPES[0])) - struct p11_kit_uri { int unrecognized; CK_INFO module; CK_TOKEN_INFO token; - CK_ATTRIBUTE attributes[NUM_ATTRIBUTE_TYPES]; - CK_ULONG n_attributes; + CK_ATTRIBUTE *attrs; char *pin_source; }; @@ -426,41 +417,12 @@ p11_kit_uri_match_token_info (P11KitUri *uri, CK_TOKEN_INFO_PTR token_info) CK_ATTRIBUTE_PTR p11_kit_uri_get_attribute (P11KitUri *uri, CK_ATTRIBUTE_TYPE attr_type) { - CK_ULONG i; - return_val_if_fail (uri != NULL, NULL); - for (i = 0; i < uri->n_attributes; i++) { - if (uri->attributes[i].type == attr_type) - return &uri->attributes[i]; - } - - return NULL; -} - -static void -uri_take_attribute (P11KitUri *uri, CK_ATTRIBUTE_PTR attr) -{ - CK_ULONG i; - - assert (uri); - assert (attr); - - /* Replace an attribute already set */ - for (i = 0; i < uri->n_attributes; i++) { - if (uri->attributes[i].type == attr->type) { - free (uri->attributes[i].pValue); - memcpy (&uri->attributes[i], attr, sizeof (CK_ATTRIBUTE)); - memset (attr, 0, sizeof (CK_ATTRIBUTE)); - return; - } - } + if (uri->attrs == NULL) + return NULL; - /* Add one at the end */ - assert (uri->n_attributes < NUM_ATTRIBUTE_TYPES); - memcpy (&uri->attributes[uri->n_attributes], attr, sizeof (CK_ATTRIBUTE)); - memset (attr, 0, sizeof (CK_ATTRIBUTE)); - uri->n_attributes++; + return p11_attrs_find (uri->attrs, attr_type); } /** @@ -478,30 +440,11 @@ uri_take_attribute (P11KitUri *uri, CK_ATTRIBUTE_PTR attr) int p11_kit_uri_set_attribute (P11KitUri *uri, CK_ATTRIBUTE_PTR attr) { - CK_ATTRIBUTE copy; - CK_ULONG i; - return_val_if_fail (uri != NULL, P11_KIT_URI_UNEXPECTED); - return_val_if_fail (uri != NULL, P11_KIT_URI_UNEXPECTED); - - /* Make sure the attribute type is valid */ - for (i = 0; i < NUM_ATTRIBUTE_TYPES; i++) { - if (SUPPORTED_ATTRIBUTE_TYPES[i] == attr->type) - break; - } - if (i == NUM_ATTRIBUTE_TYPES) - return P11_KIT_URI_NOT_FOUND; - memcpy (©, attr, sizeof (CK_ATTRIBUTE)); + uri->attrs = p11_attrs_buildn (uri->attrs, attr, 1); + return_val_if_fail (uri->attrs != NULL, P11_KIT_URI_UNEXPECTED); - /* Duplicate the value */ - if (attr->pValue && attr->ulValueLen && attr->ulValueLen != (CK_ULONG)-1) { - copy.pValue = malloc (attr->ulValueLen); - return_val_if_fail (copy.pValue != NULL, P11_KIT_URI_UNEXPECTED); - memcpy (copy.pValue, attr->pValue, attr->ulValueLen); - } - - uri_take_attribute (uri, ©); return P11_KIT_URI_OK; } @@ -520,44 +463,16 @@ p11_kit_uri_set_attribute (P11KitUri *uri, CK_ATTRIBUTE_PTR attr) int p11_kit_uri_clear_attribute (P11KitUri *uri, CK_ATTRIBUTE_TYPE attr_type) { - CK_ATTRIBUTE_PTR clear = NULL; - CK_ATTRIBUTE_PTR last; - CK_ULONG i; - return_val_if_fail (uri != NULL, P11_KIT_URI_UNEXPECTED); - /* Make sure the attribute type is valid */ - for (i = 0; i < NUM_ATTRIBUTE_TYPES; i++) { - if (SUPPORTED_ATTRIBUTE_TYPES[i] == attr_type) - break; - } - if (i == NUM_ATTRIBUTE_TYPES) + if (attr_type != CKA_CLASS && + attr_type != CKA_LABEL && + attr_type != CKA_ID) return P11_KIT_URI_NOT_FOUND; - /* Cleanup the values in the attribute */ - for (i = 0; i < uri->n_attributes; i++) { - if (uri->attributes[i].type == attr_type) { - clear = &uri->attributes[i]; - free (uri->attributes[i].pValue); - break; - } - } - - /* A valid attribute, but not present */ - if (clear == NULL) - return P11_KIT_URI_OK; - - assert (uri->n_attributes > 0); - uri->n_attributes--; - - /* If not the last attribute, then make last take its place */ - last = &uri->attributes[uri->n_attributes]; - if (clear != last) { - memcpy (clear, last, sizeof (CK_ATTRIBUTE)); - clear = last; - } + if (uri->attrs) + p11_attrs_remove (uri->attrs, attr_type); - memset (clear, 0, sizeof (CK_ATTRIBUTE)); return P11_KIT_URI_OK; } @@ -575,11 +490,19 @@ p11_kit_uri_clear_attribute (P11KitUri *uri, CK_ATTRIBUTE_TYPE attr_type) CK_ATTRIBUTE_PTR p11_kit_uri_get_attributes (P11KitUri *uri, CK_ULONG_PTR n_attrs) { + static CK_ATTRIBUTE empty = { CKA_INVALID, NULL, 0UL }; + return_val_if_fail (uri != NULL, NULL); - return_val_if_fail (n_attrs != NULL, NULL); - *n_attrs = uri->n_attributes; - return uri->attributes; + if (!uri->attrs) { + if (n_attrs) + *n_attrs = 0; + return ∅ + } + + if (n_attrs) + *n_attrs = p11_attrs_count (uri->attrs); + return uri->attrs; } int @@ -605,31 +528,10 @@ p11_kit_uri_set_attributes (P11KitUri *uri, CK_ATTRIBUTE_PTR attrs, void p11_kit_uri_clear_attributes (P11KitUri *uri) { - CK_ULONG i; - return_if_fail (uri != NULL); - for (i = 0; i < uri->n_attributes; i++) - free (uri->attributes[i].pValue); - uri->n_attributes = 0; -} - - -static int -match_attributes (CK_ATTRIBUTE_PTR one, CK_ATTRIBUTE_PTR two) -{ - assert (one); - assert (two); - - if (one->type != two->type) - return 0; - if (one->ulValueLen != two->ulValueLen) - return 0; - if (one->pValue == two->pValue) - return 1; - if (!one->pValue || !two->pValue) - return 0; - return memcmp (one->pValue, two->pValue, one->ulValueLen) == 0; + p11_attrs_free (uri->attrs); + uri->attrs = NULL; } /** @@ -651,7 +553,7 @@ int p11_kit_uri_match_attributes (P11KitUri *uri, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs) { - CK_ULONG j; + CK_ATTRIBUTE *attr; CK_ULONG i; return_val_if_fail (uri != NULL, 0); @@ -660,14 +562,18 @@ p11_kit_uri_match_attributes (P11KitUri *uri, CK_ATTRIBUTE_PTR attrs, if (uri->unrecognized) return 0; - for (i = 0; i < uri->n_attributes; i++) { - for (j = 0; j < n_attrs; ++j) { - if (uri->attributes[i].type == attrs[j].type) { - if (!match_attributes (&uri->attributes[i], &attrs[j])) - return 0; - break; - } - } + for (i = 0; i < n_attrs; i++) { + if (attrs[i].type != CKA_CLASS && + attrs[i].type != CKA_LABEL && + attrs[i].type != CKA_ID) + continue; + attr = NULL; + if (uri->attrs) + attr = p11_attrs_find (uri->attrs, attrs[i].type); + if (!attr) + continue; + if (!p11_attr_equal (attr, attrs + i)) + return 0; } return 1; @@ -935,9 +841,18 @@ format_struct_version (char **string, size_t *length, int *is_first, * URI. To format a URI containing all possible information use * %P11_KIT_URI_FOR_ANY * + * It's up to the caller to guarantee that the attributes set in @uri are + * those appropriate for inclusion in a URI, specifically: + * <literal>CKA_ID</literal>, <literal>CKA_LABEL</literal> + * and <literal>CKA_CLASS</literal>. The class must be one of + * <literal>CKO_DATA</literal>, <literal>CKO_SECRET_KEY</literal>, + * <literal>CKO_CERTIFICATE</literal>, <literal>CKO_PUBLIC_KEY</literal>, + * <literal>CKO_PRIVATE_KEY</literal>. + * * The resulting string should be freed with free(). * - * Returns: %P11_KIT_URI_OK if the URI was formatted successfully. + * Returns: %P11_KIT_URI_OK if the URI was formatted successfully, + * %P11_KIT_URI_UNEXPECTED if the data in @uri is invalid for a URI. */ int p11_kit_uri_format (P11KitUri *uri, P11KitUriType uri_type, char **string) @@ -1025,16 +940,16 @@ parse_string_attribute (const char *name, const char *start, const char *end, P11KitUri *uri) { unsigned char *value; - CK_ATTRIBUTE attr; + CK_ATTRIBUTE_TYPE type; size_t length; int ret; assert (start <= end); if (strcmp ("id", name) == 0) - attr.type = CKA_ID; + type = CKA_ID; else if (strcmp ("object", name) == 0) - attr.type = CKA_LABEL; + type = CKA_LABEL; else return 0; @@ -1042,9 +957,7 @@ parse_string_attribute (const char *name, const char *start, const char *end, if (ret < 0) return ret; - attr.pValue = value; - attr.ulValueLen = length; - uri_take_attribute (uri, &attr); + uri->attrs = p11_attrs_take (uri->attrs, type, value, length); return 1; } @@ -1092,7 +1005,7 @@ parse_class_attribute (const char *name, const char *start, const char *end, attr.ulValueLen = sizeof (klass); attr.type = CKA_CLASS; - uri_take_attribute (uri, &attr); + uri->attrs = p11_attrs_build (uri->attrs, &attr, NULL); return 1; } @@ -1290,7 +1203,6 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type, const char *spos, *epos; char *key = NULL; int ret; - int i; assert (string); assert (uri); @@ -1311,11 +1223,8 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type, /* Clear everything out */ memset (&uri->module, 0, sizeof (uri->module)); memset (&uri->token, 0, sizeof (uri->token)); - for (i = 0; i < uri->n_attributes; ++i) { - free (uri->attributes[i].pValue); - memset (&uri->attributes[i], 0, sizeof (CK_ATTRIBUTE)); - } - uri->n_attributes = 0; + p11_attrs_free (uri->attrs); + uri->attrs = NULL; uri->module.libraryVersion.major = (CK_BYTE)-1; uri->module.libraryVersion.minor = (CK_BYTE)-1; uri->unrecognized = 0; @@ -1376,14 +1285,10 @@ p11_kit_uri_parse (const char *string, P11KitUriType uri_type, void p11_kit_uri_free (P11KitUri *uri) { - int i; - if (!uri) return; - for (i = 0; i < uri->n_attributes; ++i) - free (uri->attributes[i].pValue); - + p11_attrs_free (uri->attrs); free (uri->pin_source); free (uri); } |