From: Tobias Brunner Date: Wed, 1 Dec 2021 16:13:35 +0000 (+0100) Subject: metadata: Add metadata factory and implementation for integer types X-Git-Tag: 5.9.5rc1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=531335ad20e8aab902e5b3aa422861b2e910ee9d;p=thirdparty%2Fstrongswan.git metadata: Add metadata factory and implementation for integer types Co-authored-by: Thomas Egerer --- diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 6d87447eac..be263efbec 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -33,6 +33,7 @@ credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ ipsec/ipsec_types.c \ +metadata/metadata_factory.c metadata/metadata_int.c \ networking/host.c networking/host_resolver.c networking/packet.c \ networking/tun_device.c networking/streams/stream_manager.c \ networking/streams/stream.c networking/streams/stream_service.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 0754d7bc5c..ca3f1e1da5 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -31,6 +31,7 @@ credentials/sets/cert_cache.c credentials/sets/mem_cred.c \ credentials/sets/callback_cred.c credentials/auth_cfg.c database/database.c \ database/database_factory.c fetcher/fetcher.c fetcher/fetcher_manager.c eap/eap.c \ ipsec/ipsec_types.c \ +metadata/metadata_factory.c metadata/metadata_int.c \ networking/host.c networking/host_resolver.c networking/packet.c \ networking/tun_device.c networking/streams/stream_manager.c \ networking/streams/stream.c networking/streams/stream_service.c \ @@ -99,6 +100,7 @@ credentials/sets/mem_cred.h credentials/sets/callback_cred.h \ credentials/auth_cfg.h credentials/credential_set.h credentials/cert_validator.h \ database/database.h database/database_factory.h fetcher/fetcher.h \ fetcher/fetcher_manager.h eap/eap.h pen/pen.h ipsec/ipsec_types.h \ +metadata/metadata.h metadata/metadata_factory.h metadata/metadata_int.h \ networking/host.h networking/host_resolver.h networking/packet.h \ networking/tun_device.h networking/streams/stream.h \ networking/streams/stream_unix.h networking/streams/stream_service_unix.h \ diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index 9c0dc69ef7..09834d3b9f 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -170,6 +170,7 @@ void library_deinit() this->public.credmgr->destroy(this->public.credmgr); this->public.creds->destroy(this->public.creds); this->public.encoding->destroy(this->public.encoding); + this->public.metadata->destroy(this->public.metadata); this->public.crypto->destroy(this->public.crypto); this->public.caps->destroy(this->public.caps); this->public.proposal->destroy(this->public.proposal); @@ -399,6 +400,7 @@ bool library_init(char *settings, const char *namespace) this->public.creds = credential_factory_create(); this->public.credmgr = credential_manager_create(); this->public.encoding = cred_encoding_create(); + this->public.metadata = metadata_factory_create(); this->public.fetcher = fetcher_manager_create(); this->public.resolver = resolver_manager_create(); this->public.db = database_factory_create(); diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 6409d3cae5..197b0fe72f 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -112,6 +112,7 @@ #include "credentials/credential_factory.h" #include "credentials/credential_manager.h" #include "credentials/cred_encoding.h" +#include "metadata/metadata_factory.h" #include "utils/chunk.h" #include "utils/capabilities.h" #include "utils/integrity_checker.h" @@ -189,6 +190,11 @@ struct library_t { */ cred_encoding_t *encoding; + /** + * Registry and factory for metadata creation + */ + metadata_factory_t *metadata; + /** * URL fetching facility */ diff --git a/src/libstrongswan/metadata/metadata.h b/src/libstrongswan/metadata/metadata.h new file mode 100644 index 0000000000..401f4dc3ba --- /dev/null +++ b/src/libstrongswan/metadata/metadata.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @defgroup metadata metadata + * @ingroup libstrongswan + * + * @defgroup metadata_t metadata + * @{ @ingroup metadata + */ + +#ifndef METADATA_H_ +#define METADATA_H_ + +#include + +typedef struct metadata_t metadata_t; + +/** + * Pre-defined metadata type for int values. Note that while the constructor and + * equals() work with integer values/types smaller than int (such values get + * promoted to int when passed via ...), get() does not and expects a pointer to + * an int variable. + */ +#define METADATA_TYPE_INT "int" + +/** + * Pre-defined metadata type for uint64_t values. Make sure to pass only + * uint64_t values/variables also to the constructor and equals() (or cast them + * appropriately there). + */ +#define METADATA_TYPE_UINT64 "uint64" + +/** + * Metadata object to allow storing arbitrary values in an encapsulated + * object. + */ +struct metadata_t { + + /** + * Return the type of the metadata object. + * + * @return string type of the metadata object + */ + const char *(*get_type)(metadata_t *this); + + /** + * Clone this metadata object. + * + * @return a cloned instance + */ + metadata_t *(*clone)(metadata_t *this); + + /** + * Compare this to another value (or values, depending on the type). + * + * @param ... value(s) (raw, not metadata_t) to compare this to + * @return TRUE if value is equal to metadata value + */ + bool (*equals)(metadata_t *this, ...); + + /** + * Retrieve the values via variadic argument(s). + * + * @param ... pointer(s) to obtain metadata value(s) + */ + void (*get)(metadata_t *this, ...); + + /** + * Destroy this metadata object. + */ + void (*destroy)(metadata_t *this); +}; + +/** + * Constructor type for metadata objects. + * + * @param type type of the metadata object, allows using the same + * constructor for different types + * @param args type-specific arguments + * @return metadata object, NULL on failure + */ +typedef metadata_t *(*metadata_create_t)(const char *type, va_list args); + +#endif /** METADATA_H_ @}*/ diff --git a/src/libstrongswan/metadata/metadata_factory.c b/src/libstrongswan/metadata/metadata_factory.c new file mode 100644 index 0000000000..4fb4443931 --- /dev/null +++ b/src/libstrongswan/metadata/metadata_factory.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "metadata_factory.h" +#include "metadata_int.h" + +#include +#include + +typedef struct private_metadata_factory_t private_metadata_factory_t; + +/** + * Private data + */ +struct private_metadata_factory_t { + + /** + * Public interface + */ + metadata_factory_t public; + + /** + * Registered metadata types (entry_t) + */ + hashtable_t *types; +}; + +/** + * Registered constructor data + */ +typedef struct { + /** Type name */ + char *type; + /** Constructor */ + metadata_create_t create; +} entry_t; + +/** + * Destroy an entry + */ +static void destroy_entry(entry_t *this) +{ + if (this) + { + free(this->type); + free(this); + } +} + +METHOD(metadata_factory_t, create, metadata_t*, + private_metadata_factory_t *this, const char *type, ...) +{ + metadata_t *metadata = NULL; + entry_t *entry; + va_list args; + + entry = this->types->get(this->types, type); + if (entry) + { + va_start(args, type); + metadata = entry->create(type, args); + va_end(args); + } + return metadata; +} + +METHOD(metadata_factory_t, register_type, void, + private_metadata_factory_t *this, const char *type, + metadata_create_t create) +{ + entry_t *entry; + + INIT(entry, + .type = strdup(type), + .create = create, + ); + + destroy_entry(this->types->put(this->types, entry->type, entry)); +} + +METHOD(metadata_factory_t, destroy, void, + private_metadata_factory_t *this) +{ + this->types->destroy_function(this->types, (void*)destroy_entry); + free(this); +} + +metadata_factory_t *metadata_factory_create() +{ + private_metadata_factory_t *this; + + INIT(this, + .public = { + .create = _create, + .register_type = _register_type, + .destroy = _destroy, + }, + .types = hashtable_create(hashtable_hash_str, hashtable_equals_str, 0), + ); + + /* register pre-defined types */ + register_type(this, METADATA_TYPE_INT, metadata_create_int); + register_type(this, METADATA_TYPE_UINT64, metadata_create_int); + + return &this->public; +} diff --git a/src/libstrongswan/metadata/metadata_factory.h b/src/libstrongswan/metadata/metadata_factory.h new file mode 100644 index 0000000000..c7a56aafed --- /dev/null +++ b/src/libstrongswan/metadata/metadata_factory.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @defgroup metadata_factory metadata_factory + * @{ @ingroup metadata + */ + +#ifndef METADATA_FACTORY_H_ +#define METADATA_FACTORY_H_ + +#include "metadata.h" + +typedef struct metadata_factory_t metadata_factory_t; + +/** + * Create a factory for dealing with metadata objects. + */ +struct metadata_factory_t { + + /** + * Create a metadata object of the given type. + * + * @param type type of the desired metadata object + * @param ... data to wrap into the metadata object + * @return metadata handler on success, NULL otherwise + */ + metadata_t *(*create)(metadata_factory_t *this, const char *type, ...); + + /** + * Register a constructor for a given type. + * + * @param type type to register + * @param create metadata constructor + */ + void (*register_type)(metadata_factory_t *this, const char *type, + metadata_create_t create); + + /** + * Destroy a metadata_factory_t instance. + */ + void (*destroy)(metadata_factory_t *this); +}; + +/** + * Create a metadata_factory_t instance. + */ +metadata_factory_t *metadata_factory_create(); + +#endif /** METADATA_FACTORY_H_ @}*/ diff --git a/src/libstrongswan/metadata/metadata_int.c b/src/libstrongswan/metadata/metadata_int.c new file mode 100644 index 0000000000..fb2a4b36b9 --- /dev/null +++ b/src/libstrongswan/metadata/metadata_int.c @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "metadata_int.h" + +#include + +typedef struct private_metadata_t private_metadata_t; + +/** + * Private data + */ +struct private_metadata_t { + + /** + * Public interface + */ + metadata_t public; + + /** + * String representation of type. + */ + const char *type; + + /** + * Stored value. + */ + uint64_t value; +}; + +/* forward declaration */ +static metadata_t *create_generic(const char *type, uint64_t value); + +METHOD(metadata_t, get_type, const char*, + private_metadata_t *this) +{ + return this->type; +} + +METHOD(metadata_t, clone_, metadata_t*, + private_metadata_t *this) +{ + return create_generic(this->type, this->value); +} + +METHOD(metadata_t, equals, bool, + private_metadata_t *this, ...) +{ + /* bool, uint8, uint16 etc. are promoted to int when passed via ... */ + if (streq(METADATA_TYPE_INT, this->type)) + { + int value; + + VA_ARGS_GET(this, value); + return value == (int)this->value; + } + else if (streq(METADATA_TYPE_UINT64, this->type)) + { + uint64_t value; + + VA_ARGS_GET(this, value); + return value == this->value; + } + return FALSE; +} + +METHOD(metadata_t, get, void, + private_metadata_t *this, ...) +{ + /* pointers here have to match exactly, so passing e.g. a bool* or uint16_t + * are illegal */ + if (streq(METADATA_TYPE_INT, this->type)) + { + int *value; + + VA_ARGS_GET(this, value); + *value = this->value; + } + else if (streq(METADATA_TYPE_UINT64, this->type)) + { + uint64_t *value; + + VA_ARGS_GET(this, value); + *value = this->value; + } +} + +METHOD(metadata_t, destroy, void, + private_metadata_t *this) +{ + free(this); +} + +/** + * Generic constructor + */ +static metadata_t *create_generic(const char *type, uint64_t value) +{ + private_metadata_t *this; + + INIT(this, + .public = { + .get_type = _get_type, + .clone = _clone_, + .equals = _equals, + .get = _get, + .destroy = _destroy, + }, + .type = type, + .value = value, + ); + return &this->public; +} + +/* + * Described in header + */ +metadata_t *metadata_create_int(const char *type, va_list args) +{ + metadata_t *this = NULL; + + /* bool, uint8, uint16 etc. are promoted to int when passed via ... */ + if (streq(METADATA_TYPE_INT, type)) + { + int int_val; + + VA_ARGS_VGET(args, int_val); + this = create_generic(METADATA_TYPE_INT, int_val); + } + else if (streq(METADATA_TYPE_UINT64, type)) + { + uint64_t uint64_val; + + VA_ARGS_VGET(args, uint64_val); + this = create_generic(METADATA_TYPE_UINT64, uint64_val); + } + return this; +} diff --git a/src/libstrongswan/metadata/metadata_int.h b/src/libstrongswan/metadata/metadata_int.h new file mode 100644 index 0000000000..e5e96420ec --- /dev/null +++ b/src/libstrongswan/metadata/metadata_int.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @defgroup metadata_int metadata_int + * @{ @ingroup metadata + */ + +#ifndef METADATA_INT_H_ +#define METADATA_INT_H_ + +#include "metadata.h" + +/** + * Create a metadata object of an integer type. + * + * @param type type name + * @param args integer of the specified type + * @return successfully created object, NULL on failure + */ +metadata_t *metadata_create_int(const char *type, va_list args); + +#endif /** METADATA_INT_H_ @}*/ diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am index a537301617..37ea107721 100644 --- a/src/libstrongswan/tests/Makefile.am +++ b/src/libstrongswan/tests/Makefile.am @@ -65,7 +65,8 @@ libstrongswan_tests_SOURCES = tests.h tests.c \ suites/test_ntru.c \ suites/test_ed25519.c \ suites/test_ed448.c \ - suites/test_signature_params.c + suites/test_signature_params.c \ + suites/test_metadata.c libstrongswan_tests_CFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ diff --git a/src/libstrongswan/tests/suites/test_metadata.c b/src/libstrongswan/tests/suites/test_metadata.c new file mode 100644 index 0000000000..4d0b1329b1 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_metadata.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2021 Tobias Brunner, codelabs GmbH + * Copyright (C) 2021 Thomas Egerer, secunet AG + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "test_suite.h" + +static struct { + const char *type; + int value; + short short_value; +} test_data_int[] = { + { "int", 3, 3 }, + { "int", SHRT_MAX, SHRT_MAX }, + { "int", INT_MAX, (short)INT_MAX }, +}; + +/** + * Compare the int value stored in the metadata object. + */ +static void equals_int(metadata_t *metadata, int _i) +{ + int got; + + ck_assert(metadata); + ck_assert(metadata->equals(metadata, test_data_int[_i].value)); + ck_assert_str_eq(test_data_int[_i].type, metadata->get_type(metadata)); + metadata->get(metadata, &got); + ck_assert_int_eq(test_data_int[_i].value, got); + + if (test_data_int[_i].value == test_data_int[_i].short_value) + { + ck_assert(metadata->equals(metadata, test_data_int[_i].short_value)); + ck_assert_int_eq(test_data_int[_i].short_value, got); + } + else + { + ck_assert(!metadata->equals(metadata, test_data_int[_i].short_value)); + ck_assert(test_data_int[_i].short_value != got); + } +} + +START_TEST(test_create_equals_int) +{ + metadata_t *metadata, *clone; + + metadata = lib->metadata->create(lib->metadata, test_data_int[_i].type, + test_data_int[_i].value); + + equals_int(metadata, _i); + clone = metadata->clone(metadata); + equals_int(clone, _i); + + clone->destroy(clone); + metadata->destroy(metadata); +} +END_TEST + +static struct { + const char *type; + uint64_t value; + short short_value; +} test_data_uint64[] = { + { "uint64", 3, 3 }, + { "uint64", SHRT_MAX, SHRT_MAX }, + { "uint64", UINT64_MAX, (short)UINT64_MAX }, +}; + +/** + * Compare the uint64_t value stored in the metadata object. + */ +static void equals_uint64(metadata_t *metadata, int _i) +{ + uint64_t got; + + ck_assert(metadata); + ck_assert(metadata->equals(metadata, test_data_uint64[_i].value)); + ck_assert_str_eq(test_data_uint64[_i].type, metadata->get_type(metadata)); + metadata->get(metadata, &got); + ck_assert_int_eq(test_data_uint64[_i].value, got); + + if (test_data_uint64[_i].value == test_data_uint64[_i].short_value) + { + ck_assert(metadata->equals(metadata, (uint64_t)test_data_uint64[_i].short_value)); + ck_assert_int_eq(test_data_uint64[_i].short_value, got); + } + else + { + ck_assert(!metadata->equals(metadata, (uint64_t)test_data_uint64[_i].short_value)); + ck_assert(test_data_uint64[_i].short_value != got); + } +} + +START_TEST(test_create_equals_uint64) +{ + metadata_t *metadata, *clone; + + metadata = lib->metadata->create(lib->metadata, test_data_uint64[_i].type, + test_data_uint64[_i].value); + + equals_uint64(metadata, _i); + clone = metadata->clone(metadata); + equals_uint64(clone, _i); + + clone->destroy(clone); + metadata->destroy(metadata); +} +END_TEST + +Suite *metadata_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("metadata"); + + tc = tcase_create("integer types"); + tcase_add_loop_test(tc, test_create_equals_int, 0, countof(test_data_int)); + tcase_add_loop_test(tc, test_create_equals_uint64, 0, countof(test_data_uint64)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h index f8fa9378ab..7ff66d76bf 100644 --- a/src/libstrongswan/tests/tests.h +++ b/src/libstrongswan/tests/tests.h @@ -61,3 +61,4 @@ TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://") TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519) TEST_SUITE_DEPEND(ed448_suite_create, PRIVKEY_GEN, KEY_ED448) TEST_SUITE(signature_params_suite_create) +TEST_SUITE(metadata_suite_create)