diff options
-rw-r--r-- | p11-kit/iter.c | 59 | ||||
-rw-r--r-- | p11-kit/iter.h | 7 | ||||
-rw-r--r-- | p11-kit/tests/test-iter.c | 111 | ||||
-rw-r--r-- | trust/extract-info.c | 8 | ||||
-rw-r--r-- | trust/extract.c | 2 | ||||
-rw-r--r-- | trust/tests/frob-nss-trust.c | 6 | ||||
-rw-r--r-- | trust/tests/test-bundle.c | 2 | ||||
-rw-r--r-- | trust/tests/test-cer.c | 2 | ||||
-rw-r--r-- | trust/tests/test-extract.c | 2 | ||||
-rw-r--r-- | trust/tests/test-openssl.c | 2 |
10 files changed, 144 insertions, 57 deletions
diff --git a/p11-kit/iter.c b/p11-kit/iter.c index c144165..1c2994d 100644 --- a/p11-kit/iter.c +++ b/p11-kit/iter.c @@ -52,8 +52,6 @@ typedef struct _Callback { struct _Callback *next; } Callback; -#define MAX_OBJECTS 64 - /** * P11KitIter: * @@ -77,7 +75,8 @@ struct p11_kit_iter { CK_ULONG saw_slots; /* The results of C_FindObjects */ - CK_OBJECT_HANDLE objects[MAX_OBJECTS]; + CK_OBJECT_HANDLE *objects; + CK_ULONG max_objects; CK_ULONG num_objects; CK_ULONG saw_objects; @@ -93,11 +92,13 @@ struct p11_kit_iter { int iterating : 1; int match_nothing : 1; int keep_session : 1; + int preload_results : 1; }; /** * p11_kit_iter_new: * @uri: (allow-none): a PKCS\#11 URI to filter on, or %NULL + * @behavior: various behavior flags for iterator * * Create a new PKCS\#11 iterator for iterating over objects. Only * objects that match the @uri will be returned by the iterator. @@ -111,7 +112,8 @@ struct p11_kit_iter { * with p11_kit_iter_free() */ P11KitIter * -p11_kit_iter_new (P11KitUri *uri) +p11_kit_iter_new (P11KitUri *uri, + P11KitIterBehavior behavior) { P11KitIter *iter; CK_ATTRIBUTE *attrs; @@ -149,6 +151,7 @@ p11_kit_iter_new (P11KitUri *uri) } iter->session_flags = CKF_SERIAL_SESSION; + iter->preload_results = !(behavior & P11_KIT_ITER_BUSY_SESSIONS); return iter; } @@ -515,6 +518,7 @@ move_next_session (P11KitIter *iter) CK_RV p11_kit_iter_next (P11KitIter *iter) { + CK_ULONG batch; CK_ULONG count; CK_BBOOL matches; CK_RV rv; @@ -566,20 +570,36 @@ p11_kit_iter_next (P11KitIter *iter) iter->num_objects = 0; iter->saw_objects = 0; - rv = (iter->module->C_FindObjects) (iter->session, iter->objects, - MAX_OBJECTS, &iter->num_objects); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - /* - * Done searching on this session, although there are still - * objects outstanding, which will be returned on next - * iterations. - */ - if (iter->num_objects != MAX_OBJECTS) { - iter->searching = 0; - iter->searched = 1; - (iter->module->C_FindObjectsFinal) (iter->session); + for (;;) { + if (iter->max_objects - iter->num_objects == 0) { + iter->max_objects = iter->max_objects ? iter->max_objects * 2 : 64; + iter->objects = realloc (iter->objects, iter->max_objects * sizeof (CK_ULONG)); + return_val_if_fail (iter->objects != NULL, CKR_HOST_MEMORY); + } + + batch = iter->max_objects - iter->num_objects; + rv = (iter->module->C_FindObjects) (iter->session, + iter->objects + iter->num_objects, + batch, &count); + if (rv != CKR_OK) + return finish_iterating (iter, rv); + + iter->num_objects += count; + + /* + * Done searching on this session, although there are still + * objects outstanding, which will be returned on next + * iterations. + */ + if (batch != count) { + iter->searching = 0; + iter->searched = 1; + (iter->module->C_FindObjectsFinal) (iter->session); + break; + } + + if (!iter->preload_results) + break; } } @@ -635,7 +655,7 @@ p11_kit_iter_get_slot (P11KitIter *iter) * The session may be closed after the next p11_kit_iter_next() call * unless p11_kit_iter_keep_session() is called. * - * Returns: the slot of the current matching object + * Returns: the session used to find the current matching object */ CK_SESSION_HANDLE p11_kit_iter_get_session (P11KitIter *iter) @@ -815,6 +835,7 @@ p11_kit_iter_free (P11KitIter *iter) finish_iterating (iter, CKR_OK); p11_array_free (iter->modules); p11_attrs_free (iter->match_attrs); + free (iter->objects); free (iter->slots); for (cb = iter->callbacks; cb != NULL; cb = next) { diff --git a/p11-kit/iter.h b/p11-kit/iter.h index 2b87273..d8534ec 100644 --- a/p11-kit/iter.h +++ b/p11-kit/iter.h @@ -47,11 +47,16 @@ extern "C" { typedef struct p11_kit_iter P11KitIter; +typedef enum { + P11_KIT_ITER_BUSY_SESSIONS = 1 << 1, +} P11KitIterBehavior; + typedef CK_RV (* p11_kit_iter_callback) (P11KitIter *iter, CK_BBOOL *matches, void *data); -P11KitIter * p11_kit_iter_new (P11KitUri *uri); +P11KitIter * p11_kit_iter_new (P11KitUri *uri, + P11KitIterBehavior behavior); void p11_kit_iter_free (P11KitIter *iter); diff --git a/p11-kit/tests/test-iter.c b/p11-kit/tests/test-iter.c index 18b5ed6..309a0ad 100644 --- a/p11-kit/tests/test-iter.c +++ b/p11-kit/tests/test-iter.c @@ -38,6 +38,7 @@ #define P11_KIT_FUTURE_UNSTABLE_API 1 #include "attrs.h" +#include "dict.h" #include "iter.h" #include "library.h" #include "message.h" @@ -99,7 +100,7 @@ test_all (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, P11_KIT_ITER_BUSY_SESSIONS); p11_kit_iter_begin (iter, modules); at = 0; @@ -183,7 +184,7 @@ test_callback (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_callback (iter, on_iter_callback, "callback", NULL); p11_kit_iter_begin (iter, modules); @@ -228,7 +229,7 @@ test_callback_fails (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_callback (iter, on_callback_fail, "callback", NULL); p11_kit_iter_begin (iter, modules); @@ -258,7 +259,7 @@ test_callback_destroyer (void) P11KitIter *iter; int value = 1; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_callback (iter, on_callback_fail, &value, on_destroy_increment); p11_kit_iter_free (iter); @@ -283,7 +284,7 @@ test_with_session (void) rv = mock_C_OpenSession (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); assert (rv == CKR_OK); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &mock_module, 0, session); at= 0; @@ -336,7 +337,7 @@ test_with_slot (void) rv = mock_module.C_Initialize (NULL); assert (rv == CKR_OK); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &mock_module, MOCK_SLOT_ONE_ID, 0); at= 0; @@ -382,7 +383,7 @@ test_with_module (void) rv = mock_module.C_Initialize (NULL); assert (rv == CKR_OK); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &mock_module, 0, 0); at= 0; @@ -423,7 +424,7 @@ test_keep_session (void) rv = mock_module.C_Initialize (NULL); assert (rv == CKR_OK); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &mock_module, 0, 0); rv = p11_kit_iter_next (iter); @@ -453,7 +454,7 @@ test_unrecognized (void) uri = p11_kit_uri_new (); p11_kit_uri_set_unrecognized (uri, 1); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -489,7 +490,7 @@ test_uri_with_type (void) ret = p11_kit_uri_parse ("pkcs11:object-type=public", P11_KIT_URI_FOR_OBJECT, uri); assert_num_eq (ret, P11_KIT_URI_OK); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -535,7 +536,7 @@ test_filter (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_filter (iter, attrs, 2); p11_kit_iter_begin (iter, modules); @@ -575,7 +576,7 @@ test_session_flags (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_set_session_flags (iter, CKF_RW_SESSION); p11_kit_iter_begin (iter, modules); @@ -616,7 +617,7 @@ test_module_match (void) ret = p11_kit_uri_parse ("pkcs11:library-description=MOCK%20LIBRARY", P11_KIT_URI_FOR_MODULE, uri); assert_num_eq (P11_KIT_URI_OK, ret); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -651,7 +652,7 @@ test_module_mismatch (void) ret = p11_kit_uri_parse ("pkcs11:library-description=blah", P11_KIT_URI_FOR_MODULE, uri); assert_num_eq (P11_KIT_URI_OK, ret); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -686,7 +687,7 @@ test_token_match (void) ret = p11_kit_uri_parse ("pkcs11:manufacturer=TEST%20MANUFACTURER", P11_KIT_URI_FOR_TOKEN, uri); assert_num_eq (P11_KIT_URI_OK, ret); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -721,7 +722,7 @@ test_token_mismatch (void) ret = p11_kit_uri_parse ("pkcs11:manufacturer=blah", P11_KIT_URI_FOR_TOKEN, uri); assert_num_eq (P11_KIT_URI_OK, ret); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_uri_free (uri); p11_kit_iter_begin (iter, modules); @@ -755,7 +756,7 @@ test_getslotlist_fail_first (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetSlotList = mock_C_GetSlotList__fail_first; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); at= 0; @@ -788,7 +789,7 @@ test_getslotlist_fail_late (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetSlotList = mock_C_GetSlotList__fail_late; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); at= 0; @@ -821,7 +822,7 @@ test_open_session_fail (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_OpenSession = mock_C_OpenSession__fails; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); at= 0; @@ -854,7 +855,7 @@ test_find_init_fail (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_FindObjectsInit = mock_C_FindObjectsInit__fails; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); at= 0; @@ -887,7 +888,7 @@ test_find_objects_fail (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_FindObjects = mock_C_FindObjects__fails; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); at= 0; @@ -923,7 +924,7 @@ test_load_attributes (void) modules = initialize_and_get_modules (); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin (iter, modules); attrs = p11_attrs_buildn (NULL, types, 2); @@ -981,7 +982,7 @@ test_load_attributes_none (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { @@ -1015,7 +1016,7 @@ test_load_attributes_fail_first (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetAttributeValue = mock_C_GetAttributeValue__fail_first; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { @@ -1049,7 +1050,7 @@ test_load_attributes_fail_late (void) memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetAttributeValue = mock_C_GetAttributeValue__fail_late; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_begin_with (iter, &module, 0, 0); while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { @@ -1067,6 +1068,64 @@ test_load_attributes_fail_late (void) assert (rv == CKR_OK); } +static void +test_many (void *flags) +{ + P11KitIterBehavior behavior; + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE handle; + p11_dict *seen; + P11KitIter *iter; + CK_RV rv; + int count; + int i; + + static CK_OBJECT_CLASS data = CKO_DATA; + static CK_ATTRIBUTE object[] = { + { CKA_VALUE, "blah", 4 }, + { CKA_CLASS, &data, sizeof (data) }, + { CKA_ID, "ID1", 3 }, + { CKA_INVALID }, + }; + + behavior = 0; + if (strstr (flags, "busy-sessions")) + behavior |= P11_KIT_ITER_BUSY_SESSIONS; + + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert_num_eq (rv, CKR_OK); + + rv = mock_C_OpenSession (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert_num_eq (rv, CKR_OK); + + for (i = 0; i < 10000; i++) + mock_module_add_object (MOCK_SLOT_ONE_ID, object); + + seen = p11_dict_new (p11_dict_ulongptr_hash, p11_dict_ulongptr_equal, free, NULL); + iter = p11_kit_iter_new (NULL, behavior); + p11_kit_iter_add_filter (iter, object, 3); + p11_kit_iter_begin_with (iter, &mock_module, 0, session); + + count = 0; + while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { + handle = p11_kit_iter_get_object (iter); + assert (p11_dict_get (seen, &handle) == NULL); + if (!p11_dict_set (seen, memdup (&handle, sizeof (handle)), "x")) + assert_not_reached (); + count++; + } + + assert_num_eq (rv, CKR_CANCEL); + assert_num_eq (count, 10000); + + p11_kit_iter_free (iter); + p11_dict_free (seen); + + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); +} + int main (int argc, char *argv[]) @@ -1099,6 +1158,8 @@ main (int argc, p11_test (test_load_attributes_none, "/iter/test_load_attributes_none"); p11_test (test_load_attributes_fail_first, "/iter/test_load_attributes_fail_first"); p11_test (test_load_attributes_fail_late, "/iter/test_load_attributes_fail_late"); + p11_testx (test_many, "", "/iter/test-many"); + p11_testx (test_many, "busy-sessions", "/iter/test-many-busy"); return p11_test_run (argc, argv); } diff --git a/trust/extract-info.c b/trust/extract-info.c index 133b1cd..a645d31 100644 --- a/trust/extract-info.c +++ b/trust/extract-info.c @@ -51,7 +51,7 @@ static p11_dict * load_stapled_extensions (CK_FUNCTION_LIST_PTR module, - CK_SLOT_ID slot_id, + CK_SESSION_HANDLE session, CK_ATTRIBUTE *id) { CK_OBJECT_CLASS extension = CKO_X_CERTIFICATE_EXTENSION; @@ -79,9 +79,9 @@ load_stapled_extensions (CK_FUNCTION_LIST_PTR module, if (!id->pValue || !id->ulValueLen) return stapled; - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_filter (iter, match, 2); - p11_kit_iter_begin_with (iter, module, slot_id, 0); + p11_kit_iter_begin_with (iter, module, 0, session); while (rv == CKR_OK) { rv = p11_kit_iter_next (iter); @@ -291,7 +291,7 @@ extract_info (P11KitIter *iter, attr = p11_attrs_find_valid (ex->attrs, CKA_ID); if (attr) { ex->stapled = load_stapled_extensions (p11_kit_iter_get_module (iter), - p11_kit_iter_get_slot (iter), + p11_kit_iter_get_session (iter), attr); if (!ex->stapled) return false; diff --git a/trust/extract.c b/trust/extract.c index 10f45df..d5ceb13 100644 --- a/trust/extract.c +++ b/trust/extract.c @@ -440,7 +440,7 @@ p11_trust_extract (int argc, limit_modules_if_necessary (modules, ex.flags); - iter = p11_kit_iter_new (uri); + iter = p11_kit_iter_new (uri, 0); p11_kit_iter_add_callback (iter, p11_extract_info_load_filter, &ex, NULL); p11_kit_iter_add_filter (iter, match, p11_attrs_count (match)); diff --git a/trust/tests/frob-nss-trust.c b/trust/tests/frob-nss-trust.c index a81b5e2..fd74db7 100644 --- a/trust/tests/frob-nss-trust.c +++ b/trust/tests/frob-nss-trust.c @@ -108,7 +108,7 @@ dump_trust_module (const char *path) rv = p11_kit_module_initialize (module); return_val_if_fail (rv == CKR_OK, 1); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_filter (iter, &match, 1); p11_kit_iter_begin_with (iter, module, 0, 0); @@ -168,7 +168,7 @@ compare_trust_modules (const char *path1, rv = p11_kit_module_initialize (module2); return_val_if_fail (rv == CKR_OK, 1); - iter = p11_kit_iter_new (NULL); + iter = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_filter (iter, &match, 1); p11_kit_iter_begin_with (iter, module1, 0, 0); @@ -182,7 +182,7 @@ compare_trust_modules (const char *path1, p11_attrs_purge (check); /* Check that this object exists */ - iter2 = p11_kit_iter_new (NULL); + iter2 = p11_kit_iter_new (NULL, 0); p11_kit_iter_add_filter (iter2, check, p11_attrs_count (check)); p11_kit_iter_begin_with (iter2, module2, 0, 0); rv = p11_kit_iter_next (iter2); diff --git a/trust/tests/test-bundle.c b/trust/tests/test-bundle.c index bff135e..10f89d2 100644 --- a/trust/tests/test-bundle.c +++ b/trust/tests/test-bundle.c @@ -74,7 +74,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL); + test.iter = p11_kit_iter_new (NULL, 0); p11_extract_info_init (&test.ex); diff --git a/trust/tests/test-cer.c b/trust/tests/test-cer.c index c48a5ab..fc4d007 100644 --- a/trust/tests/test-cer.c +++ b/trust/tests/test-cer.c @@ -74,7 +74,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL); + test.iter = p11_kit_iter_new (NULL, 0); p11_extract_info_init (&test.ex); diff --git a/trust/tests/test-extract.c b/trust/tests/test-extract.c index e860996..b121b21 100644 --- a/trust/tests/test-extract.c +++ b/trust/tests/test-extract.c @@ -154,7 +154,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL); + test.iter = p11_kit_iter_new (NULL, 0); p11_extract_info_init (&test.ex); } diff --git a/trust/tests/test-openssl.c b/trust/tests/test-openssl.c index 7479812..93f8692 100644 --- a/trust/tests/test-openssl.c +++ b/trust/tests/test-openssl.c @@ -78,7 +78,7 @@ setup (void *unused) rv = test.module.C_Initialize (NULL); assert_num_eq (CKR_OK, rv); - test.iter = p11_kit_iter_new (NULL); + test.iter = p11_kit_iter_new (NULL, 0); p11_extract_info_init (&test.ex); |