diff options
-rw-r--r-- | Makefile-test.am | 5 | ||||
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/tss2/tss2_tctildr.h | 7 | ||||
-rw-r--r-- | lib/tss2-tctildr.def | 1 | ||||
-rw-r--r-- | lib/tss2-tctildr.map | 1 | ||||
-rw-r--r-- | man/Tss2_TctiLdr_Initialize.3.in | 39 | ||||
-rw-r--r-- | src/tss2-esys/esys_context.c | 2 | ||||
-rw-r--r-- | src/tss2-tcti/tctildr-dl.c | 1 | ||||
-rw-r--r-- | src/tss2-tcti/tctildr.c | 99 | ||||
-rw-r--r-- | src/tss2-tcti/tctildr.h | 4 | ||||
-rw-r--r-- | test/unit/esys-nulltcti.c | 3 | ||||
-rw-r--r-- | test/unit/tctildr-init.c | 62 | ||||
-rw-r--r-- | test/unit/tctildr.c | 77 |
14 files changed, 275 insertions, 30 deletions
diff --git a/Makefile-test.am b/Makefile-test.am index 4d5adad7..5fe871cf 100644 --- a/Makefile-test.am +++ b/Makefile-test.am @@ -250,7 +250,8 @@ test_unit_tcti_mssim_SOURCES = test/unit/tcti-mssim.c \ test_unit_tctildr_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS) test_unit_tctildr_LDADD = $(CMOCKA_LIBS) $(libutil) test_unit_tctildr_LDFLAGS = -Wl,--wrap=calloc,--wrap=free \ - -Wl,--wrap=tctildr_finalize_data,--wrap=tctildr_get_tcti + -Wl,--wrap=tctildr_finalize_data,--wrap=tctildr_get_tcti \ + -Wl,--wrap=strlen,--wrap=strchr,--wrap=strcpy test_unit_tctildr_SOURCES = test/unit/tctildr.c \ src/tss2-tcti/tctildr.c @@ -282,7 +283,7 @@ test_unit_tctildr_init_CFLAGS = $(CMOCKA_CFLAGS) $(TESTS_CFLAGS) test_unit_tctildr_init_LDADD = $(CMOCKA_LIBS) $(libutil) \ $(libtss2_tcti_device) $(libtss2_tcti_mssim) test_unit_tctildr_init_LDFLAGS = -Wl,--wrap=calloc,--wrap=free \ - -Wl,--wrap=tctildr_get_tcti,--wrap=tctildr_finalize_data + -Wl,--wrap=tctildr_get_tcti,--wrap=tctildr_finalize_data,--wrap=strlen test_unit_tctildr_init_SOURCES = test/unit/tctildr-init.c \ src/tss2-tcti/tctildr.c diff --git a/Makefile.am b/Makefile.am index e4221808..76e91cb8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -388,6 +388,9 @@ man/man3/%.3 : man/%.3.in $(srcdir)/man/man-postlude.troff man/man7/%.7 : man/%.7.in $(srcdir)/man/man-postlude.troff $(AM_V_GEN)$(call make_man,$@,$<,$(srcdir)/man/man-postlude.troff) +install-man: install-man3 install-man7 + $(LN_S) Tss2_TctiLdr_Initialize.3 $(DESTDIR)$(man3dir)/Tss2_TctiLdr_Initialize_Ex.3 + EXTRA_DIST += dist/tpm-udev.rules if WITH_UDEVRULESPREFIX diff --git a/configure.ac b/configure.ac index 8131258e..a5a599d4 100644 --- a/configure.ac +++ b/configure.ac @@ -27,6 +27,7 @@ AX_CHECK_ENABLE_DEBUG([info]) AC_PROG_CXX AC_PROG_CC +AC_PROG_LN_S AC_USE_SYSTEM_EXTENSIONS LT_INIT() LT_LIB_DLLOAD diff --git a/include/tss2/tss2_tctildr.h b/include/tss2/tss2_tctildr.h index 32492db8..f589dff6 100644 --- a/include/tss2/tss2_tctildr.h +++ b/include/tss2/tss2_tctildr.h @@ -14,8 +14,11 @@ void Tss2_TctiLdr_Finalize (TSS2_TCTI_CONTEXT **context); TSS2_RC -Tss2_TctiLdr_Initialize (const char *name, - const char *conf, +Tss2_TctiLdr_Initialize_Ex (const char *name, + const char *conf, + TSS2_TCTI_CONTEXT **context); +TSS2_RC +Tss2_TctiLdr_Initialize (const char *nameConf, TSS2_TCTI_CONTEXT **context); #endif /* TSS2_TCTILDR_H */ diff --git a/lib/tss2-tctildr.def b/lib/tss2-tctildr.def index 56a1c8a8..a7540082 100644 --- a/lib/tss2-tctildr.def +++ b/lib/tss2-tctildr.def @@ -2,3 +2,4 @@ LIBRARY tss2-tctildr EXPORTS Tss2_TctiLdr_Finalize Tss2_TctiLdr_Initialize + Tss2_TctiLdr_Initialize_Ex diff --git a/lib/tss2-tctildr.map b/lib/tss2-tctildr.map index f90dba4e..fe4da098 100644 --- a/lib/tss2-tctildr.map +++ b/lib/tss2-tctildr.map @@ -2,6 +2,7 @@ global: Tss2_TctiLdr_Finalize; Tss2_TctiLdr_Initialize; + Tss2_TctiLdr_Initialize_Ex; local: *; }; diff --git a/man/Tss2_TctiLdr_Initialize.3.in b/man/Tss2_TctiLdr_Initialize.3.in index a38429b1..8e5fffaa 100644 --- a/man/Tss2_TctiLdr_Initialize.3.in +++ b/man/Tss2_TctiLdr_Initialize.3.in @@ -9,26 +9,45 @@ initialize a TCTI context. .B #include <tss2/tss2_tctildr.h> .sp .sp -.BI "TSS2_RC Tss2_TctiLdr_Initialize (const char " "*name" ", const char " "*conf" ", TSS2_TCTI_CONTEXT " "**context" ");" +.BI "TSS2_RC Tss2_TctiLdr_Initialize (const char " "*nameConf" ", TSS2_TCTI_CONTEXT " "**context" ");" +.sp +.BI "TSS2_RC Tss2_TctiLdr_Initialize_Ex (const char " "*name" ", const char " "*conf" ", TSS2_TCTI_CONTEXT " "**context" ");" .sp .SH DESCRIPTION The .BR Tss2_TctiLdr_Initialize () -function initializes a TCTI context used to communicate with the TPM2 or +and +.BR Tss2_TctiLdr_Initialize_Ex () +functions initialize a TCTI context used to communicate with the TPM2 or some intermediate component in the TCG TPM2 software stack. .sp .BR Tss2_TctiLdr_Initialize () -takes two strings that encode name of the TCTI library the -caller wishes to instantiate and the desired configuration in the +takes a single string that encodes both the name of the TCTI library the +caller wishes to instantiate and its desired configuration in the +.I nameConf +parameter. +.I nameConf +is a string comprised of two substrings: .I name and .I conf parameters respectively. +These substrings are combined with +.I name +first, separated by a single ':' / colon character: 'name:conf'. Consult +the section titled TCTI CONFIG for information about the encoding of these +strings. The .I context parameter is used to return a reference to the TCTI context created by the function. .sp +.BR Tss2_TctiLdr_Initialize_Ex () +behaves identically to the +.BR Tss2_TctiLdr_Initialize () +function with the exception that the TCTI name and configuration are passed +as separate strings. The encoding of these strings is described in section +TCTI_CONFIG. .SH TCTI CONFIG If the .I name @@ -70,6 +89,18 @@ string is not interpreted by the TctiLdr init functions and is passed unaltered to the initialization function for the selected TCTI. The format for this string is TCTI specific. .sp +The +.BR Tss2_TctiLdr_Initialize +function is passed the +.I name +and +.I conf +strings as a single parameter. In this case the +.I name +and +.I conf +strings are concatinated with a single ':' / colon character separating them. +.sp For a more thorough discussion of the TCTILDR API see the \*(lqTCG TSS 2.0 TPM Command Transmission Interface (TCTI) API Specification\*(rq. .SH RETURN VALUE diff --git a/src/tss2-esys/esys_context.c b/src/tss2-esys/esys_context.c index 2b7755e0..b912a688 100644 --- a/src/tss2-esys/esys_context.c +++ b/src/tss2-esys/esys_context.c @@ -65,7 +65,7 @@ Esys_Initialize(ESYS_CONTEXT ** esys_context, TSS2_TCTI_CONTEXT * tcti, /* If no tcti was provided, initialize the default one. */ if (tcti == NULL) { - r = Tss2_TctiLdr_Initialize (NULL, NULL, &tcti); + r = Tss2_TctiLdr_Initialize (NULL, &tcti); goto_if_error(r, "Initialize default tcti.", cleanup_return); } diff --git a/src/tss2-tcti/tctildr-dl.c b/src/tss2-tcti/tctildr-dl.c index 5e94877d..3187e855 100644 --- a/src/tss2-tcti/tctildr-dl.c +++ b/src/tss2-tcti/tctildr-dl.c @@ -188,6 +188,7 @@ tctildr_get_tcti(const char *name, TSS2_TCTI_CONTEXT **tcti, void **data) { + LOG_DEBUG("name: \"%s\", conf: \"%s\"", name, conf); if (tcti == NULL) { LOG_ERROR("tcticontext must not be NULL"); return TSS2_TCTI_RC_BAD_REFERENCE; diff --git a/src/tss2-tcti/tctildr.c b/src/tss2-tcti/tctildr.c index a0e34af5..950d2b86 100644 --- a/src/tss2-tcti/tctildr.c +++ b/src/tss2-tcti/tctildr.c @@ -11,6 +11,16 @@ #include <errno.h> #include <inttypes.h> +#if defined(__linux__) +#include <linux/limits.h> +#elif defined(_MSC_VER) +#include <windows.h> +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#else +#include <limits.h> +#endif #include <stdlib.h> #include <string.h> @@ -87,6 +97,63 @@ tcti_from_info(TSS2_TCTI_INFO_FUNC infof, return TSS2_RC_SUCCESS; } +/* + * name_conf in the form "tcti-name:tcti-conf" + * copies 'tcti-name' component to 'name' buffer + * copies 'tcti-conf' component to 'conf' buffer + * handled name_conf forms: + * - "", ":" -> both name and conf are left unchanged + * - "tcti-name", "tcti-name:" -> tcti-name copied to 'name', 'conf' + * unchanged + * - ":tcti-conf" -> tcti-conf copied to 'conf', 'name' unchanged + * - "tcti-name:tcti-conf" - "tcti-name" copied to 'name,', "tcti-conf" + * copied to 'conf' + */ +TSS2_RC +tctildr_conf_parse (const char *name_conf, + char *name, + char *conf) +{ + char *split; + size_t combined_length; + + LOG_DEBUG ("name_conf: \"%s\"", name_conf); + if (name == NULL || conf == NULL || name_conf == NULL) { + LOG_ERROR ("no params may be NULL"); + return TSS2_TCTI_RC_BAD_REFERENCE; + } + combined_length = strlen (name_conf); + if (combined_length > PATH_MAX - 1) { + LOG_ERROR ("combined conf length must be between 0 and PATH_MAX"); + return TSS2_TCTI_RC_BAD_VALUE; + } + if (combined_length == 0) + return TSS2_RC_SUCCESS; + split = strchr (name_conf, ':'); + if (split == NULL) { + /* no ':' tcti name only */ + strcpy (name, name_conf); + LOG_DEBUG ("TCTI name: \"%s\"", name); + return TSS2_RC_SUCCESS; + } + if (name_conf[0] != '\0' && name_conf[0] != ':') { + /* name is more than empty string */ + size_t name_length = split - name_conf; + if (name_length > PATH_MAX) { + return TSS2_TCTI_RC_BAD_VALUE; + } + memcpy (name, name_conf, name_length); + name [name_length] = '\0'; + LOG_DEBUG ("TCTI name: \"%s\"", name); + } + if (split [1] != '\0') { + /* conf is more than empty string */ + strcpy (conf, &split [1]); + LOG_DEBUG ("TCTI conf: \"%s\"", conf); + } + + return TSS2_RC_SUCCESS; +} TSS2_TCTILDR_CONTEXT* tctildr_context_cast (TSS2_TCTI_CONTEXT *ctx) { @@ -202,19 +269,27 @@ Tss2_TctiLdr_Finalize (TSS2_TCTI_CONTEXT **tctiContext) } TSS2_RC -Tss2_TctiLdr_Initialize (const char *name, - const char *conf, - TSS2_TCTI_CONTEXT **tctiContext) +Tss2_TctiLdr_Initialize_Ex (const char *name, + const char *conf, + TSS2_TCTI_CONTEXT **tctiContext) { TSS2_TCTILDR_CONTEXT *ldr_ctx = NULL; TSS2_RC rc; void *dl_handle = NULL; + const char *local_name = NULL, *local_conf = NULL; if (tctiContext == NULL) { return TSS2_TCTI_RC_BAD_VALUE; } *tctiContext = NULL; - rc = tctildr_get_tcti (name, conf, tctiContext, &dl_handle); + /* Ignore 'name' and 'conf' if they're NULL or empty string */ + if (name != NULL && strcmp (name, "")) { + local_name = name; + } + if (conf != NULL && strcmp (conf, "")) { + local_conf = conf; + } + rc = tctildr_get_tcti (local_name, local_conf, tctiContext, &dl_handle); if (rc != TSS2_RC_SUCCESS) { LOG_ERROR ("Failed to instantiate TCTI"); goto err; @@ -245,3 +320,19 @@ err: tctildr_finalize_data (&dl_handle); return rc; } + +TSS2_RC +Tss2_TctiLdr_Initialize (const char *nameConf, + TSS2_TCTI_CONTEXT **tctiContext) +{ + char name [PATH_MAX] = { 0, }, conf [PATH_MAX] = { 0, }; + TSS2_RC rc; + + if (nameConf == NULL) { + return Tss2_TctiLdr_Initialize_Ex (NULL, NULL, tctiContext); + } + rc = tctildr_conf_parse (nameConf, name, conf); + if (rc != TSS2_RC_SUCCESS) + return rc; + return Tss2_TctiLdr_Initialize_Ex (name, conf, tctiContext); +} diff --git a/src/tss2-tcti/tctildr.h b/src/tss2-tcti/tctildr.h index 87d6ab20..3746b861 100644 --- a/src/tss2-tcti/tctildr.h +++ b/src/tss2-tcti/tctildr.h @@ -35,6 +35,10 @@ tcti_from_info(TSS2_TCTI_INFO_FUNC infof, const char* conf, TSS2_TCTI_CONTEXT **tcti); TSS2_RC +tctildr_conf_parse (const char *name_conf, + char *name, + char *conf); +TSS2_RC tctildr_transmit ( TSS2_TCTI_CONTEXT *tctiContext, size_t command_size, diff --git a/test/unit/esys-nulltcti.c b/test/unit/esys-nulltcti.c index cf428477..35f4cdf2 100644 --- a/test/unit/esys-nulltcti.c +++ b/test/unit/esys-nulltcti.c @@ -33,8 +33,7 @@ tcti_fake_finalize(TSS2_TCTI_CONTEXT *tctiContext) } TSS2_RC -__wrap_Tss2_TctiLdr_Initialize (const char *name, - const char *conf, +__wrap_Tss2_TctiLdr_Initialize (const char *nameConf, TSS2_TCTI_CONTEXT **tcti) { if (tcti == NULL) diff --git a/test/unit/tctildr-init.c b/test/unit/tctildr-init.c index 97ac6e6c..f5b1e2e5 100644 --- a/test/unit/tctildr-init.c +++ b/test/unit/tctildr-init.c @@ -4,7 +4,11 @@ */ #include <inttypes.h> +#if defined(__linux__) +#include <linux/limits.h> +#else #include <limits.h> +#endif #include <stdarg.h> #include <stdbool.h> #include <stdlib.h> @@ -54,11 +58,37 @@ __wrap_free (void *ptr) } #define TEST_INIT_SECOND_RC 0xdead555 static void -tctildr_init_null_context_test (void **state) +tctildr_init_ex_null_test (void **state) { TSS2_RC rc; - rc = Tss2_TctiLdr_Initialize (NULL, NULL, NULL); + rc = Tss2_TctiLdr_Initialize_Ex (NULL, NULL, NULL); + assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE); +} +static void +tctildr_init_null_test (void **state) +{ + TSS2_RC rc; + + rc = Tss2_TctiLdr_Initialize (NULL, NULL); + assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE); +} +#define NAME_CONF_STR (char*)0xf100d +size_t __real_strlen (const char *s); +size_t +__wrap_strlen (const char *s) +{ + if (s != NAME_CONF_STR) + return __real_strlen (s); + return mock_type (size_t); +} +static void +tctildr_init_conf_fail_test (void **state) +{ + TSS2_RC rc; + + will_return (__wrap_strlen, PATH_MAX); + rc = Tss2_TctiLdr_Initialize (NAME_CONF_STR, NULL); assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE); } TSS2_RC @@ -77,28 +107,28 @@ __wrap_tctildr_get_tcti (const char *name, void __wrap_tctildr_finalize_data (void **data) {} static void -tctildr_init_tcti_default_fail (void **state) +tctildr_init_ex_default_fail (void **state) { TSS2_RC rc; TSS2_TCTI_CONTEXT *context; will_return (__wrap_tctildr_get_tcti, TSS2_TCTI_RC_BAD_REFERENCE); - rc = Tss2_TctiLdr_Initialize (NULL, NULL, &context); + rc = Tss2_TctiLdr_Initialize_Ex (NULL, NULL, &context); assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE); } static void -tctildr_init_tcti_from_file_fail (void **state) +tctildr_init_ex_from_file_fail (void **state) { TSS2_RC rc; TSS2_TCTI_CONTEXT *context; will_return (__wrap_tctildr_get_tcti, TSS2_TCTI_RC_BAD_REFERENCE); - rc = Tss2_TctiLdr_Initialize ("foo", NULL, &context); + rc = Tss2_TctiLdr_Initialize_Ex ("foo", NULL, &context); assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE); } static void -tctildr_init_calloc_fail_test (void **state) +tctildr_init_ex_calloc_fail_test (void **state) { TSS2_RC rc; TSS2_TCTI_CONTEXT *ctx; @@ -108,11 +138,11 @@ tctildr_init_calloc_fail_test (void **state) will_return (__wrap_tctildr_get_tcti, TEST_TCTI_HANDLE); will_return (__wrap_calloc, NULL); - rc = Tss2_TctiLdr_Initialize (NULL, NULL, &ctx); + rc = Tss2_TctiLdr_Initialize_Ex (NULL, NULL, &ctx); assert_int_equal (rc, TSS2_RC_SUCCESS); } static void -tctildr_init_success_test (void **state) +tctildr_init_ex_success_test (void **state) { TSS2_RC rc; TSS2_TCTI_CONTEXT *ctx; @@ -122,7 +152,7 @@ tctildr_init_success_test (void **state) will_return (__wrap_tctildr_get_tcti, TEST_TCTI_HANDLE); will_return (__wrap_calloc, &tctildr_ctx); - rc = Tss2_TctiLdr_Initialize (NULL, NULL, &ctx); + rc = Tss2_TctiLdr_Initialize_Ex (NULL, NULL, &ctx); assert_int_equal (rc, TSS2_RC_SUCCESS); } static void @@ -154,11 +184,13 @@ int main (int argc, char* arvg[]) { const struct CMUnitTest tests[] = { - cmocka_unit_test (tctildr_init_null_context_test), - cmocka_unit_test (tctildr_init_tcti_default_fail), - cmocka_unit_test (tctildr_init_tcti_from_file_fail), - cmocka_unit_test (tctildr_init_calloc_fail_test), - cmocka_unit_test (tctildr_init_success_test), + cmocka_unit_test (tctildr_init_ex_null_test), + cmocka_unit_test (tctildr_init_null_test), + cmocka_unit_test (tctildr_init_conf_fail_test), + cmocka_unit_test (tctildr_init_ex_default_fail), + cmocka_unit_test (tctildr_init_ex_from_file_fail), + cmocka_unit_test (tctildr_init_ex_calloc_fail_test), + cmocka_unit_test (tctildr_init_ex_success_test), cmocka_unit_test (tctildr_finalize_null_ref_test), cmocka_unit_test (tctildr_finalize_null_ctx_test), cmocka_unit_test (tctildr_finalize_test), diff --git a/test/unit/tctildr.c b/test/unit/tctildr.c index 008a95b1..f45defd5 100644 --- a/test/unit/tctildr.c +++ b/test/unit/tctildr.c @@ -7,6 +7,7 @@ #include <config.h> #endif +#include <limits.h> #include <stdio.h> #include <stddef.h> #include <stdlib.h> @@ -150,7 +151,77 @@ tcti_from_info_success (void **state) TSS2_RC rc = tcti_from_info (local_info, NULL, &tcti_ctx_ptr); assert_int_equal (rc, TSS2_RC_SUCCESS); } +void +test_conf_parse_null (void **state) +{ + TSS2_RC rc = tctildr_conf_parse (NULL, NULL, NULL); + assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE); +} +#define NAME_CONF_STR (char*)0xf100d +size_t __real_strlen (const char *s); +size_t +__wrap_strlen (const char *s) +{ + if (s != NAME_CONF_STR) + return __real_strlen (s); + return mock_type (size_t); +} +char* __real_strchr (const char *s, int c); +char* +__wrap_strchr (const char *s, int c) +{ + if (s != NAME_CONF_STR) + return __real_strchr (s, c); + return mock_type (char*); +} +char* __real_strcpy(char *dest, const char *src); +char* +__wrap_strcpy(char *dest, const char *src) +{ + if (src != NAME_CONF_STR) + return __real_strcpy (dest, src); + return mock_type (char*); +} +void +test_conf_parse_bad_length (void **state) +{ + char name_buf[0], conf_buf[0]; + will_return (__wrap_strlen, PATH_MAX); + TSS2_RC rc = tctildr_conf_parse (NAME_CONF_STR, name_buf, conf_buf); + assert_int_equal (rc, TSS2_TCTI_RC_BAD_VALUE); +} +void +test_conf_parse_empty_str (void **state) +{ + char name_buf[0], conf_buf[0]; + TSS2_RC rc = tctildr_conf_parse ("", name_buf, conf_buf); + assert_int_equal (rc, TSS2_RC_SUCCESS); +} +void +test_conf_parse_no_colon (void **state) +{ + char name_buf[50] = { 0, }, conf_buf[50] = { 0, }; + TSS2_RC rc = tctildr_conf_parse ("foo", name_buf, conf_buf); + assert_int_equal (rc, TSS2_RC_SUCCESS); +} +void +test_conf_parse_name_colon (void **state) +{ + char name_buf[50] = { 0, }, conf_buf[50] = { 0, }; + TSS2_RC rc = tctildr_conf_parse ("foo:", name_buf, conf_buf); + assert_string_equal (name_buf, "foo"); + assert_int_equal (rc, TSS2_RC_SUCCESS); +} +void +test_conf_parse_name_colon_conf (void **state) +{ + char name_buf[50] = { 0, }, conf_buf[50] = { 0, }; + TSS2_RC rc = tctildr_conf_parse ("foo:bar", name_buf, conf_buf); + assert_string_equal (name_buf, "foo"); + assert_string_equal (conf_buf, "bar"); + assert_int_equal (rc, TSS2_RC_SUCCESS); +} int main(void) { @@ -163,6 +234,12 @@ main(void) cmocka_unit_test(tcti_from_info_info_null), cmocka_unit_test(tcti_from_info_info_fail), cmocka_unit_test(tcti_from_info_success), + cmocka_unit_test(test_conf_parse_null), + cmocka_unit_test(test_conf_parse_bad_length), + cmocka_unit_test(test_conf_parse_empty_str), + cmocka_unit_test(test_conf_parse_no_colon), + cmocka_unit_test(test_conf_parse_name_colon), + cmocka_unit_test(test_conf_parse_name_colon_conf), }; return cmocka_run_group_tests (tests, NULL, NULL); } |