summaryrefslogtreecommitdiffstats
path: root/src/tests/key-store-search.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/key-store-search.cpp')
-rw-r--r--src/tests/key-store-search.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/src/tests/key-store-search.cpp b/src/tests/key-store-search.cpp
new file mode 100644
index 0000000..4070b0d
--- /dev/null
+++ b/src/tests/key-store-search.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2017-2020 [Ribose Inc](https://www.ribose.com).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 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.
+ */
+
+#include <algorithm>
+#include <set>
+#include "../librekey/key_store_pgp.h"
+#include "pgp-key.h"
+
+#include "rnp_tests.h"
+#include "support.h"
+
+/* This test adds some fake keys to a key store and tests some of
+ * the search functions.
+ */
+TEST_F(rnp_tests, test_key_store_search)
+{
+ // create our store
+ rnp_key_store_t *store = new rnp_key_store_t(PGP_KEY_STORE_GPG, "", global_ctx);
+ store->disable_validation = true;
+
+ // some fake key data
+ static const struct {
+ const char *keyid;
+ size_t count; // number of keys like this to add to the store
+ const char *userids[5]; // NULL terminator required on array and strings
+ } testdata[] = {{"000000000000AAAA", 1, {"user1-1", NULL}},
+ {"000000000000BBBB", 2, {"user2", "user1-2", NULL}},
+ {"000000000000CCCC", 1, {"user3", NULL}},
+ {"FFFFFFFFFFFFFFFF", 0, {NULL}}};
+ // add our fake test keys
+ for (size_t i = 0; i < ARRAY_SIZE(testdata); i++) {
+ for (size_t n = 0; n < testdata[i].count; n++) {
+ pgp_key_t key;
+
+ key.pkt().tag = PGP_PKT_PUBLIC_KEY;
+ key.pkt().version = PGP_V4;
+ key.pkt().alg = PGP_PKA_RSA;
+
+ // set the keyid
+ assert_true(rnp::hex_decode(
+ testdata[i].keyid, (uint8_t *) key.keyid().data(), key.keyid().size()));
+ // keys should have different grips otherwise rnp_key_store_add_key will fail here
+ pgp_key_grip_t &grip = (pgp_key_grip_t &) key.grip();
+ assert_true(rnp::hex_decode(testdata[i].keyid, grip.data(), grip.size()));
+ grip[0] = (uint8_t) n;
+ // and fingerprint
+ pgp_fingerprint_t &fp = (pgp_fingerprint_t &) key.fp();
+ assert_true(
+ rnp::hex_decode(testdata[i].keyid, fp.fingerprint, PGP_FINGERPRINT_SIZE));
+ fp.fingerprint[0] = (uint8_t) n;
+ fp.length = PGP_FINGERPRINT_SIZE;
+ // set the userids
+ for (size_t uidn = 0; testdata[i].userids[uidn]; uidn++) {
+ pgp_transferable_userid_t tuid;
+ tuid.uid.tag = PGP_PKT_USER_ID;
+ tuid.uid.uid_len = strlen(testdata[i].userids[uidn]);
+ tuid.uid.uid = (uint8_t *) malloc(tuid.uid.uid_len);
+ assert_non_null(tuid.uid.uid);
+ memcpy(tuid.uid.uid, testdata[i].userids[uidn], tuid.uid.uid_len);
+ key.add_uid(tuid);
+ }
+ // add to the store
+ assert_true(rnp_key_store_add_key(store, &key));
+ }
+ }
+
+ // keyid search
+ for (size_t i = 0; i < ARRAY_SIZE(testdata); i++) {
+ std::string keyid = testdata[i].keyid;
+ std::set<pgp_key_t *> seen_keys;
+ for (pgp_key_t *key = rnp_tests_get_key_by_id(store, keyid); key;
+ key = rnp_tests_get_key_by_id(store, keyid, key)) {
+ // check that the keyid actually matches
+ assert_true(cmp_keyid(key->keyid(), keyid));
+ // check that we have not already encountered this key pointer
+ assert_int_equal(seen_keys.count(key), 0);
+ // keep track of what key pointers we have seen
+ seen_keys.insert(key);
+ }
+ assert_int_equal(seen_keys.size(), testdata[i].count);
+ }
+ // keyid search (by_name)
+ for (size_t i = 0; i < ARRAY_SIZE(testdata); i++) {
+ std::set<pgp_key_t *> seen_keys;
+ pgp_key_t * key = NULL;
+ key = rnp_tests_get_key_by_id(store, testdata[i].keyid);
+ while (key) {
+ // check that the keyid actually matches
+ assert_true(cmp_keyid(key->keyid(), testdata[i].keyid));
+ // check that we have not already encountered this key pointer
+ assert_int_equal(seen_keys.count(key), 0);
+ // keep track of what key pointers we have seen
+ seen_keys.insert(key);
+ // this only returns false on error, regardless of whether it found a match
+ key = rnp_tests_get_key_by_id(store, testdata[i].keyid, key);
+ }
+ // check the count
+ assert_int_equal(seen_keys.size(), testdata[i].count);
+ }
+
+ // userid search (literal)
+ for (auto &key : store->keys) {
+ for (size_t i = 0; i < key.uid_count(); i++) {
+ key.get_uid(i).valid = true;
+ }
+ }
+ for (size_t i = 0; i < ARRAY_SIZE(testdata); i++) {
+ for (size_t uidn = 0; testdata[i].userids[uidn]; uidn++) {
+ std::set<pgp_key_t *> seen_keys;
+ const std::string userid = testdata[i].userids[uidn];
+ pgp_key_t * key = rnp_tests_key_search(store, userid);
+ while (key) {
+ // check that the userid actually matches
+ bool found = false;
+ for (unsigned j = 0; j < key->uid_count(); j++) {
+ if (key->get_uid(j).str == userid) {
+ found = true;
+ }
+ }
+ assert_true(found);
+ // check that we have not already encountered this key pointer
+ assert_int_equal(seen_keys.count(key), 0);
+ // keep track of what key pointers we have seen
+ seen_keys.insert(key);
+ key = rnp_tests_get_key_by_id(store, testdata[i].keyid, key);
+ }
+ // check the count
+ assert_int_equal(seen_keys.size(), testdata[i].count);
+ }
+ }
+
+ // cleanup
+ delete store;
+}
+
+TEST_F(rnp_tests, test_key_store_search_by_name)
+{
+ const pgp_key_t *key;
+ pgp_key_t * primsec;
+ pgp_key_t * subsec;
+ pgp_key_t * primpub;
+ pgp_key_t * subpub;
+
+ // load pubring
+ rnp_key_store_t *pub_store =
+ new rnp_key_store_t(PGP_KEY_STORE_KBX, "data/keyrings/3/pubring.kbx", global_ctx);
+ assert_true(rnp_key_store_load_from_path(pub_store, NULL));
+ // load secring
+ rnp_key_store_t *sec_store =
+ new rnp_key_store_t(PGP_KEY_STORE_G10, "data/keyrings/3/private-keys-v1.d", global_ctx);
+ pgp_key_provider_t key_provider(rnp_key_provider_store, pub_store);
+ assert_true(rnp_key_store_load_from_path(sec_store, &key_provider));
+
+ /* Main key fingerprint and id:
+ 4F2E62B74E6A4CD333BC19004BE147BB22DF1E60, 4BE147BB22DF1E60
+ Subkey fingerprint and id:
+ 10793E367EE867C32E358F2AA49BAE05C16E8BC8, A49BAE05C16E8BC8
+ */
+
+ /* Find keys and subkeys by fingerprint, id and userid */
+ primsec = rnp_tests_get_key_by_fpr(sec_store, "4F2E62B74E6A4CD333BC19004BE147BB22DF1E60");
+ assert_non_null(primsec);
+ key = rnp_tests_get_key_by_id(sec_store, "4BE147BB22DF1E60");
+ assert_true(key == primsec);
+ subsec = rnp_tests_get_key_by_fpr(sec_store, "10793E367EE867C32E358F2AA49BAE05C16E8BC8");
+ assert_non_null(subsec);
+ assert_true(primsec != subsec);
+ key = rnp_tests_get_key_by_id(sec_store, "A49BAE05C16E8BC8");
+ assert_true(key == subsec);
+
+ primpub = rnp_tests_get_key_by_fpr(pub_store, "4F2E62B74E6A4CD333BC19004BE147BB22DF1E60");
+ assert_non_null(primpub);
+ assert_true(primsec != primpub);
+ subpub = rnp_tests_get_key_by_fpr(pub_store, "10793E367EE867C32E358F2AA49BAE05C16E8BC8");
+ assert_true(primpub != subpub);
+ assert_true(subpub != subsec);
+ key = rnp_tests_key_search(pub_store, "test1");
+ assert_true(key == primpub);
+
+ /* Try other searches */
+ key = rnp_tests_get_key_by_fpr(sec_store, "4f2e62b74e6a4cd333bc19004be147bb22df1e60");
+ assert_true(key == primsec);
+ key = rnp_tests_get_key_by_fpr(sec_store, "0x4f2e62b74e6a4cd333bc19004be147bb22df1e60");
+ assert_true(key == primsec);
+ key = rnp_tests_get_key_by_id(pub_store, "4BE147BB22DF1E60");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, "4be147bb22df1e60");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, "0x4be147bb22df1e60");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, "22df1e60");
+ assert_null(key);
+ key = rnp_tests_get_key_by_id(pub_store, "0x22df1e60");
+ assert_null(key);
+ key = rnp_tests_get_key_by_id(pub_store, "4be1 47bb 22df 1e60");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, "4be147bb 22df1e60");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, " 4be147bb\t22df1e60 ");
+ assert_true(key == primpub);
+ key = rnp_tests_get_key_by_id(pub_store, "test1");
+ assert_null(key);
+ /* Try negative searches */
+ assert_null(rnp_tests_get_key_by_fpr(sec_store, "4f2e62b74e6a4cd333bc19004be147bb22df1e"));
+ assert_null(rnp_tests_get_key_by_fpr(sec_store, "2e62b74e6a4cd333bc19004be147bb22df1e60"));
+ assert_null(rnp_tests_get_key_by_id(sec_store, "4be147bb22dfle60"));
+ assert_null(rnp_tests_get_key_by_id(sec_store, ""));
+ assert_null(rnp_tests_get_key_by_id(sec_store, "test11"));
+ assert_null(rnp_tests_get_key_by_id(sec_store, "atest1"));
+
+ // cleanup
+ delete pub_store;
+ delete sec_store;
+}