diff --git a/common/meson.build b/common/meson.build index ec584c00..07b17c56 100644 --- a/common/meson.build +++ b/common/meson.build @@ -1,5 +1,53 @@ install_headers('pkcs11.h', 'pkcs11x.h', subdir: 'p11-kit-1/p11-kit') +libp11_asn1_deps = [] + +if with_asn1 + libp11_asn1_sources = [ + 'asn1.c', + 'oid.c', + ] + + basic_asn_h = custom_target( + 'basic.asn.h', + output: 'basic.asn.h', + input: 'basic.asn', + command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], + ) + + pkix_asn_h = custom_target( + 'pkix.asn.h', + output: 'pkix.asn.h', + input: 'pkix.asn', + command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], + ) + + openssl_asn_h = custom_target( + 'openssl.asn.h', + output: 'openssl.asn.h', + input: 'openssl.asn', + command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], + ) + + asn_h_dep = declare_dependency( + sources: [basic_asn_h, pkix_asn_h, openssl_asn_h], + ) + + libp11_asn1 = static_library( + 'p11-asn1', libp11_asn1_sources, + gnu_symbol_visibility: 'hidden', + include_directories: configinc, + ) + + libp11_asn1_dep = declare_dependency( + include_directories: [configinc, commoninc], + link_with: libp11_asn1, + dependencies: [asn_h_dep] + libtasn1_deps, + ) + + libp11_asn1_deps += libp11_asn1_dep +endif + libp11_common_sources = [ 'argv.c', 'attrs.c', @@ -35,7 +83,7 @@ libp11_library = static_library('p11-library', 'library.c', include_directories: configinc) libp11_library_dep = declare_dependency(link_with: libp11_library, - dependencies: [libp11_common_dep] + thread_deps + libintl_deps) + dependencies: [libp11_common_dep] + libp11_asn1_deps + thread_deps + libintl_deps) libp11_library_whole_dep = declare_dependency(link_whole: libp11_library, dependencies: [libp11_common_dep] + thread_deps + libintl_deps) @@ -66,54 +114,6 @@ libp11_tool = static_library('p11-tool', libp11_tool_sources, libp11_tool_dep = declare_dependency(link_with: libp11_tool, dependencies: [libp11_common_dep]) -libp11_asn1_deps = [] - -if with_asn1 - libp11_asn1_sources = [ - 'asn1.c', - 'oid.c', - ] - - basic_asn_h = custom_target( - 'basic.asn.h', - output: 'basic.asn.h', - input: 'basic.asn', - command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], - ) - - pkix_asn_h = custom_target( - 'pkix.asn.h', - output: 'pkix.asn.h', - input: 'pkix.asn', - command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], - ) - - openssl_asn_h = custom_target( - 'openssl.asn.h', - output: 'openssl.asn.h', - input: 'openssl.asn', - command: [asn1Parser, '-o', '@OUTPUT@', '@INPUT@'], - ) - - asn_h_dep = declare_dependency( - sources: [basic_asn_h, pkix_asn_h, openssl_asn_h], - ) - - libp11_asn1 = static_library( - 'p11-asn1', libp11_asn1_sources, - gnu_symbol_visibility: 'hidden', - include_directories: configinc, - ) - - libp11_asn1_dep = declare_dependency( - include_directories: [configinc, commoninc], - link_with: libp11_asn1, - dependencies: [asn_h_dep] + libtasn1_deps, - ) - - libp11_asn1_deps += libp11_asn1_dep -endif - # Tests ---------------------------------------------------------------- if get_option('test') diff --git a/common/persist.c b/common/persist.c index 86f367c9..5107a02f 100644 --- a/common/persist.c +++ b/common/persist.c @@ -384,6 +384,9 @@ format_constant (CK_ATTRIBUTE *attr, case CKA_MECHANISM_TYPE: table = p11_constant_mechanisms; break; + case CKA_PROFILE_ID: + table = p11_constant_profiles; + break; default: table = NULL; }; diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 4cdc51b6..6f7e8062 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -538,7 +538,8 @@ check_LTLIBRARIES += \ mock-nine.la \ mock-ten.la \ mock-eleven.la \ - mock-twelve.la + mock-twelve.la \ + mock-thirteen.la mock_one_la_SOURCES = p11-kit/mock-module-ep.c mock_one_la_LIBADD = libp11-test.la libp11-common.la @@ -607,6 +608,10 @@ mock_twelve_la_SOURCES = p11-kit/mock-module-ep10.c mock_twelve_la_LDFLAGS = $(mock_one_la_LDFLAGS) mock_twelve_la_LIBADD = $(mock_one_la_LIBADD) +mock_thirteen_la_SOURCES = p11-kit/mock-module-ep11.c +mock_thirteen_la_LDFLAGS = $(mock_one_la_LDFLAGS) +mock_thirteen_la_LIBADD = $(mock_one_la_LIBADD) + EXTRA_DIST += \ p11-kit/fixtures \ p11-kit/templates \ diff --git a/p11-kit/fixtures/package-modules/thirteen.module b/p11-kit/fixtures/package-modules/thirteen.module new file mode 100644 index 00000000..2a5b57be --- /dev/null +++ b/p11-kit/fixtures/package-modules/thirteen.module @@ -0,0 +1,4 @@ + +module: mock-thirteen.so +managed: yes +enable-in: p11-kit-testable diff --git a/p11-kit/meson.build b/p11-kit/meson.build index 6bf9bcf3..eb87bd05 100644 --- a/p11-kit/meson.build +++ b/p11-kit/meson.build @@ -407,6 +407,10 @@ if get_option('test') test('test-export-public.sh', find_program('test-export-public.sh'), env: p11_kit_tests_env) + + test('test-profiles.sh', + find_program('test-profiles.sh'), + env: p11_kit_tests_env) endif mock_sources = { @@ -423,7 +427,8 @@ if get_option('test') 'mock-nine': ['mock-module-ep7.c'], 'mock-ten': ['mock-module-ep8.c'], 'mock-eleven': ['mock-module-ep9.c'], - 'mock-twelve': ['mock-module-ep10.c'] + 'mock-twelve': ['mock-module-ep10.c'], + 'mock-thirteen': ['mock-module-ep11.c'] } if host_system != 'windows' @@ -437,7 +442,7 @@ if get_option('test') name_suffix: module_suffix, link_args: p11_module_ldflags, link_depends: [p11_module_symbol_map], - dependencies: [libp11_test_dep]) + dependencies: [libp11_test_dep] + libp11_asn1_deps) endforeach endif diff --git a/p11-kit/mock-module-ep11.c b/p11-kit/mock-module-ep11.c new file mode 100644 index 00000000..e29765b2 --- /dev/null +++ b/p11-kit/mock-module-ep11.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2023, 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: Zoltan Fridrich + */ + +#include "config.h" + +#define CRYPTOKI_EXPORTS 1 +#include "pkcs11.h" + +#include "attrs.h" +#include "debug.h" +#include "mock.h" +#include "persist.h" + +#include +#include + +static const CK_TOKEN_INFO MOCK_TOKEN_INFO = { + "PROFILE LABEL ONE ", + "PROFILE MANUFACTURER ", + "PROFILE MODEL ", + "PROFILE SERIAL ", + CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + { 75, 175 }, + { 85, 185 }, + { '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' } +}; + +static CK_RV +override_C_GetTokenInfo (CK_SLOT_ID slot_id, + CK_TOKEN_INFO_PTR info) +{ + return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD); + + switch (slot_id) { + case MOCK_SLOT_ONE_ID: + memcpy (info, &MOCK_TOKEN_INFO, sizeof (*info)); + return CKR_OK; + case MOCK_SLOT_TWO_ID: + return CKR_TOKEN_NOT_PRESENT; + default: + return CKR_SLOT_ID_INVALID; + } +} + +static CK_RV +override_C_Initialize (CK_VOID_PTR init_args) +{ + bool ok; + size_t i, size = 0; + void *data = NULL; + const char *filename = "test-profiles.p11-kit"; + p11_mmap *map = NULL; + p11_persist *persist = NULL; + p11_array *objects = NULL; + CK_ATTRIBUTE *attrs = NULL; + CK_RV rv; + + map = p11_mmap_open (filename, NULL, &data, &size); + if (map == NULL) + return mock_C_Initialize (init_args); + + ok = p11_persist_magic (data, size); + return_val_if_fail (ok, CKR_GENERAL_ERROR); + + persist = p11_persist_new (); + return_val_if_fail (persist != NULL, CKR_HOST_MEMORY); + + objects = p11_array_new (NULL); + return_val_if_fail (objects != NULL, CKR_HOST_MEMORY); + + ok = p11_persist_read (persist, filename, (const unsigned char *)data, size, objects); + return_val_if_fail (ok, CKR_GENERAL_ERROR); + + rv = mock_C_Initialize (init_args); + for (i = 0; i < objects->num; ++i) { + attrs = p11_attrs_build (objects->elem[i], NULL); + mock_module_add_object (MOCK_SLOT_ONE_ID, attrs); + p11_attrs_free (attrs); + } + + p11_array_free (objects); + p11_persist_free (persist); + p11_mmap_close (map); + return rv; +} + +static CK_RV +override_C_Finalize (CK_VOID_PTR reserved) +{ + bool ok; + FILE *f = NULL; + const char *filename = "test-profiles.out.p11-kit"; + p11_buffer buf; + p11_persist *persist = NULL; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object = 0; + CK_ULONG count = 0; + CK_OBJECT_CLASS klass = CKO_PROFILE; + CK_BBOOL token; + CK_PROFILE_ID profile; + CK_ATTRIBUTE template = { CKA_CLASS, &klass, sizeof (klass) }; + CK_ATTRIBUTE attrs[] = { + { CKA_CLASS, &klass, sizeof (klass) }, + { CKA_TOKEN, &token, sizeof (token) }, + { CKA_PROFILE_ID, &profile, sizeof (profile) }, + { CKA_INVALID, NULL, 0 } + }; + CK_ULONG n_attrs = sizeof (attrs) / sizeof (attrs[0]); + CK_RV rv; + + ok = p11_buffer_init (&buf, 0); + return_val_if_fail (ok, CKR_HOST_MEMORY); + + persist = p11_persist_new (); + return_val_if_fail (persist != NULL, CKR_HOST_MEMORY); + + rv = mock_C_OpenSession (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + rv = mock_C_FindObjectsInit (session, &template, 1); + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + while ((rv = mock_C_FindObjects (session, &object, 1, &count)) == CKR_OK && count > 0) { + rv = mock_C_GetAttributeValue (session, object, attrs, n_attrs - 1); + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + ok = p11_persist_write (persist, attrs, &buf); + return_val_if_fail (ok, CKR_GENERAL_ERROR); + } + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + f = fopen (filename, "wb"); + return_val_if_fail (f != NULL, CKR_HOST_MEMORY); + fwrite (buf.data, 1, buf.len, f); + fclose (f); + + rv = mock_C_FindObjectsFinal (session); + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + rv = mock_C_CloseSession (session); + return_val_if_fail (rv == CKR_OK, CKR_GENERAL_ERROR); + + p11_persist_free (persist); + p11_buffer_uninit (&buf); + return mock_C_Finalize (reserved); +} + +#ifdef OS_WIN32 +__declspec(dllexport) +#endif +CK_RV +C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + mock_module_init (); + mock_module.C_Initialize = override_C_Initialize; + mock_module.C_Finalize = override_C_Finalize; + mock_module.C_GetFunctionList = C_GetFunctionList; + mock_module.C_GetTokenInfo = override_C_GetTokenInfo; + if (list == NULL) + return CKR_ARGUMENTS_BAD; + *list = &mock_module; + return CKR_OK; +} diff --git a/p11-kit/mock-module-ep9.c b/p11-kit/mock-module-ep9.c index c8d42f79..a2409d0e 100644 --- a/p11-kit/mock-module-ep9.c +++ b/p11-kit/mock-module-ep9.c @@ -127,7 +127,6 @@ override_initialize (CK_VOID_PTR init_args) CK_RV rv = mock_C_Initialize (init_args); mock_module_add_object (MOCK_SLOT_ONE_ID, cert_attrs); mock_module_add_object (MOCK_SLOT_ONE_ID, pubkey_attrs); - mock_module_add_profile (MOCK_SLOT_ONE_ID, CKP_PUBLIC_CERTIFICATES_TOKEN); return rv; } diff --git a/p11-kit/test-lists.sh b/p11-kit/test-lists.sh index fdb4ffad..ae2d30cc 100755 --- a/p11-kit/test-lists.sh +++ b/p11-kit/test-lists.sh @@ -70,6 +70,23 @@ module: one user-pin-initialized clock-on-token token-initialized +module: thirteen + uri: pkcs11:library-description=MOCK%20LIBRARY;library-manufacturer=MOCK%20MANUFACTURER + library-description: MOCK LIBRARY + library-manufacturer: MOCK MANUFACTURER + library-version: 45.145 + token: PROFILE LABEL ONE + uri: pkcs11:model=PROFILE%20MODEL;manufacturer=PROFILE%20MANUFACTURER;serial=PROFILE%20SERIAL;token=PROFILE%20LABEL%20ONE + manufacturer: PROFILE MANUFACTURER + model: PROFILE MODEL + serial-number: PROFILE SERIAL + hardware-version: 75.175 + firmware-version: 85.185 + flags: + login-required + user-pin-initialized + clock-on-token + token-initialized module: twelve uri: pkcs11:library-description=MOCK%20LIBRARY;library-manufacturer=MOCK%20MANUFACTURER library-description: MOCK LIBRARY diff --git a/p11-kit/test-objects.sh b/p11-kit/test-objects.sh index 876e20c9..b131e16a 100755 --- a/p11-kit/test-objects.sh +++ b/p11-kit/test-objects.sh @@ -44,9 +44,6 @@ Object: #5 class: public-key label: Public prefix key Object: #6 - class: profile - profile-id: public-certificates-token -Object: #7 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=TEST%20CERTIFICATE;type=cert class: certificate certificate-type: x-509 @@ -55,65 +52,38 @@ Object: #7 trusted copyable destroyable -Object: #8 +Object: #7 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=TEST%20PUBLIC%20KEY;type=public class: public-key key-type: ec label: TEST PUBLIC KEY -Object: #9 +Object: #8 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=TEST%20LABEL;type=data class: data label: TEST LABEL -Object: #10 +Object: #9 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=Public%20Capitalize%20Key;type=public class: public-key label: Public Capitalize Key -Object: #11 +Object: #10 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=Public%20prefix%20key;type=public class: public-key label: Public prefix key -Object: #12 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=TEST%20LABEL;type=data - class: data - label: TEST LABEL -Object: #13 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=Public%20Capitalize%20Key;type=public - class: public-key - label: Public Capitalize Key -Object: #14 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=Public%20prefix%20key;type=public - class: public-key - label: Public prefix key -Object: #15 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=RSA;type=public - class: public-key - key-type: rsa - label: RSA -Object: #16 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=EC;type=public - class: public-key - key-type: ec - label: EC -Object: #17 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=SPKI;type=public - class: public-key - key-type: ec - label: SPKI -Object: #18 +Object: #11 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=TEST%20LABEL;type=data class: data label: TEST LABEL -Object: #19 +Object: #12 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=Public%20Capitalize%20Key;type=public class: public-key label: Public Capitalize Key -Object: #20 +Object: #13 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=Public%20prefix%20key;type=public class: public-key label: Public prefix key EOF - if ! "$abs_top_builddir"/p11-kit/p11-kit-testable list-objects -q "pkcs11:" > list.out; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable list-objects -q "pkcs11:token=TEST%20LABEL" > list.out; then assert_fail "unable to run: p11-kit list-objects" fi @@ -139,16 +109,12 @@ Object: #2 class: data label: TEST LABEL Object: #3 - uri: pkcs11:model=PUBKEY%20MODEL;manufacturer=PUBKEY%20MANUFACTURER;serial=PUBKEY%20SERIAL;token=PUBKEY%20LABEL;object=TEST%20LABEL;type=data - class: data - label: TEST LABEL -Object: #4 uri: pkcs11:model=TEST%20MODEL;manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL;token=TEST%20LABEL;object=TEST%20LABEL;type=data class: data label: TEST LABEL EOF - if ! "$abs_top_builddir"/p11-kit/p11-kit-testable list-objects -q "pkcs11:type=data" > list.out; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable list-objects -q "pkcs11:token=TEST%20LABEL;type=data" > list.out; then assert_fail "unable to run: p11-kit list-objects" fi diff --git a/p11-kit/test-profiles.sh b/p11-kit/test-profiles.sh index 4b26b01e..20d88433 100755 --- a/p11-kit/test-profiles.sh +++ b/p11-kit/test-profiles.sh @@ -18,11 +18,80 @@ teardown() { } test_list_profiles() { + cat > test-profiles.p11-kit < list.exp < list.out; then + assert_fail "unable to run: p11-kit list-profiles" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_list_profiles_session() { + cat > test-profiles.p11-kit < list.exp < list.out; then + assert_fail "unable to run: p11-kit list-profiles" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_list_profiles_empty() { + cat > list.exp < list.out; then + if ! "$abs_top_builddir"/p11-kit/p11-kit-testable list-profiles -q "pkcs11:token=PROFILE%20LABEL%20ONE" > list.out; then assert_fail "unable to run: p11-kit list-profiles" fi @@ -33,6 +102,111 @@ EOF fi } +test_add_profile() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_add_profile_empty() { + cat > list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_add_profile_duplicate() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_add_profile_session_duplicate() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + test_add_profile_nonexistent_token() { cat > list.exp < test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_delete_profile_last() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_delete_profile_empty() { + cat > list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_delete_profile_multiple() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +test_delete_profile_session() { + cat > test-profiles.p11-kit < list.exp < list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains wrong results" + fi +} + +run test_list_profiles test_list_profiles_session test_list_profiles_empty test_add_profile test_add_profile_empty test_add_profile_duplicate test_add_profile_session_duplicate test_add_profile_nonexistent_token test_delete_profile test_delete_profile_last test_delete_profile_empty test_delete_profile_multiple test_delete_profile_session