summaryrefslogtreecommitdiffstats
path: root/src/tests/ffi-uid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/ffi-uid.cpp')
-rw-r--r--src/tests/ffi-uid.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/src/tests/ffi-uid.cpp b/src/tests/ffi-uid.cpp
new file mode 100644
index 0000000..c8aada9
--- /dev/null
+++ b/src/tests/ffi-uid.cpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 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 <rnp/rnp.h>
+#include "rnp_tests.h"
+#include "support.h"
+
+TEST_F(rnp_tests, test_ffi_uid_properties)
+{
+ rnp_ffi_t ffi = NULL;
+ assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
+ assert_true(load_keys_gpg(ffi, "data/test_uid_validity/key-uids-pub.pgp"));
+
+ rnp_key_handle_t key = NULL;
+ assert_rnp_success(rnp_locate_key(ffi, "keyid", "F6E741D1DF582D90", &key));
+ assert_non_null(key);
+
+ size_t uids = 0;
+ assert_rnp_success(rnp_key_get_uid_count(key, &uids));
+ assert_int_equal(uids, 4);
+
+ rnp_uid_handle_t uid = NULL;
+ assert_rnp_failure(rnp_key_get_uid_handle_at(NULL, 0, &uid));
+ assert_rnp_failure(rnp_key_get_uid_handle_at(key, 0, NULL));
+ assert_rnp_failure(rnp_key_get_uid_handle_at(key, 100, &uid));
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_non_null(uid);
+
+ uint32_t uid_type = 0;
+ assert_rnp_failure(rnp_uid_get_type(NULL, &uid_type));
+ assert_rnp_failure(rnp_uid_get_type(uid, NULL));
+ assert_rnp_success(rnp_uid_get_type(uid, &uid_type));
+ assert_int_equal(uid_type, RNP_USER_ID);
+
+ size_t size = 0;
+ void * data = NULL;
+ assert_rnp_failure(rnp_uid_get_data(NULL, &data, &size));
+ assert_rnp_failure(rnp_uid_get_data(uid, NULL, &size));
+ assert_rnp_failure(rnp_uid_get_data(uid, &data, NULL));
+ assert_rnp_success(rnp_uid_get_data(uid, &data, &size));
+ assert_int_equal(size, 12);
+ assert_int_equal(memcmp(data, "userid-valid", size), 0);
+ rnp_buffer_destroy(data);
+
+ bool primary = false;
+ assert_rnp_failure(rnp_uid_is_primary(NULL, &primary));
+ assert_rnp_failure(rnp_uid_is_primary(uid, NULL));
+ assert_rnp_success(rnp_uid_is_primary(uid, &primary));
+ assert_true(primary);
+ rnp_uid_handle_destroy(uid);
+
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_uid_get_data(uid, &data, &size));
+ assert_int_equal(size, 14);
+ assert_int_equal(memcmp(data, "userid-expired", size), 0);
+ rnp_buffer_destroy(data);
+ assert_rnp_success(rnp_uid_is_primary(uid, &primary));
+ assert_false(primary);
+ rnp_uid_handle_destroy(uid);
+
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 2, &uid));
+ assert_rnp_success(rnp_uid_get_data(uid, &data, &size));
+ assert_int_equal(size, 14);
+ assert_int_equal(memcmp(data, "userid-invalid", size), 0);
+ rnp_buffer_destroy(data);
+ assert_rnp_success(rnp_uid_is_primary(uid, &primary));
+ assert_false(primary);
+ rnp_uid_handle_destroy(uid);
+
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 3, &uid));
+ assert_rnp_success(rnp_uid_get_type(uid, &uid_type));
+ assert_int_equal(uid_type, RNP_USER_ATTR);
+ assert_rnp_success(rnp_uid_get_data(uid, &data, &size));
+ assert_int_equal(size, 3038);
+ rnp_buffer_destroy(data);
+ assert_rnp_success(rnp_uid_is_primary(uid, &primary));
+ assert_false(primary);
+ rnp_uid_handle_destroy(uid);
+ rnp_key_handle_destroy(key);
+
+ rnp_ffi_destroy(ffi);
+}
+
+TEST_F(rnp_tests, test_ffi_uid_validity)
+{
+ rnp_ffi_t ffi = NULL;
+ assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
+ assert_true(load_keys_gpg(ffi, "data/test_uid_validity/key-uids-with-invalid.pgp"));
+
+ rnp_key_handle_t key = NULL;
+ assert_rnp_success(rnp_locate_key(ffi, "keyid", "F6E741D1DF582D90", &key));
+ assert_non_null(key);
+
+ size_t uids = 0;
+ assert_rnp_success(rnp_key_get_uid_count(key, &uids));
+ assert_int_equal(uids, 4);
+
+ /* userid 0 : valid */
+ rnp_uid_handle_t uid = NULL;
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ bool valid = false;
+ assert_rnp_failure(rnp_uid_is_valid(NULL, &valid));
+ assert_rnp_failure(rnp_uid_is_valid(uid, NULL));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ /* userid 1 : self-sig marks key as expired, but uid is still valid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ /* userid 2 : invalid (malformed signature data) */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 2, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_false(valid);
+ rnp_uid_handle_destroy(uid);
+
+ /* userid 3: valid userattr */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 3, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+
+ /* Try to locate key via all uids */
+ rnp_key_handle_t newkey = NULL;
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &newkey));
+ assert_non_null(newkey);
+ rnp_key_handle_destroy(newkey);
+ newkey = NULL;
+ /* even if signature marks key as expired uid is still valid and usable */
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-expired", &newkey));
+ assert_non_null(newkey);
+ rnp_key_handle_destroy(newkey);
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-invalid", &newkey));
+ assert_null(newkey);
+
+ /* Now import key with valid signature for the userid 2 */
+ assert_true(import_pub_keys(ffi, "data/test_uid_validity/key-uids-pub.pgp"));
+ uids = 0;
+ assert_rnp_success(rnp_key_get_uid_count(key, &uids));
+ assert_int_equal(uids, 4);
+
+ /* userid 0 : valid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ /* userid 1 : key is expired via self-cert, but uid is valid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ /* userid 2 : valid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 2, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ /* userid 3 : valid userattr */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 3, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+
+ /* now we should be able to locate key via userid-invalid */
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-invalid", &newkey));
+ assert_non_null(newkey);
+ rnp_key_handle_destroy(newkey);
+
+ /* Now import key with revoked primary userid */
+ assert_true(import_pub_keys(ffi, "data/test_uid_validity/key-uids-revoked-valid.pgp"));
+ uids = 0;
+ assert_rnp_success(rnp_key_get_uid_count(key, &uids));
+ assert_int_equal(uids, 4);
+
+ /* userid 0 : invalid since it is revoked */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_false(valid);
+ bool primary = true;
+ assert_rnp_success(rnp_uid_is_primary(uid, &primary));
+ assert_false(primary);
+ rnp_uid_handle_destroy(uid);
+
+ /* Primary userid now should be userid-expired */
+ char *uid_str = NULL;
+ assert_rnp_success(rnp_key_get_primary_uid(key, &uid_str));
+ assert_non_null(uid_str);
+ assert_string_equal(uid_str, "userid-expired");
+ rnp_buffer_destroy(uid_str);
+
+ /* We should not be able to find key via userid-valid */
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &newkey));
+ assert_null(newkey);
+
+ rnp_key_handle_destroy(key);
+
+ /* Load expired key with single uid: still has primary uid as it has valid self-cert */
+ assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
+ assert_true(import_pub_keys(ffi, "data/test_uid_validity/key-expired.pgp"));
+ assert_rnp_success(rnp_locate_key(ffi, "keyid", "4BE147BB22DF1E60", &key));
+ assert_non_null(key);
+ uid_str = NULL;
+ assert_rnp_success(rnp_key_get_primary_uid(key, &uid_str));
+ assert_string_equal(uid_str, "test1");
+ rnp_buffer_destroy(uid_str);
+ rnp_key_handle_destroy(key);
+
+ /* UID with expired self-certification signature */
+ assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
+ assert_true(import_pub_keys(ffi, "data/test_uid_validity/key-uid-expired-sig.pgp"));
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "expired_uid_sig", &key));
+ assert_null(key);
+ assert_rnp_success(rnp_locate_key(ffi, "keyid", "129195E05B0943CB", &key));
+ assert_non_null(key);
+ uid_str = NULL;
+ assert_rnp_failure(rnp_key_get_primary_uid(key, &uid_str));
+ assert_null(uid_str);
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_false(valid);
+ rnp_uid_handle_destroy(uid);
+ assert_rnp_success(rnp_key_is_valid(key, &valid));
+ /* key is valid since there is a subkey with valid binding signature */
+ assert_true(valid);
+ rnp_key_handle_destroy(key);
+
+ /* UID with expired self-certification on primary uid signature */
+ assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
+ assert_true(import_pub_keys(ffi, "data/test_uid_validity/key-uid-prim-expired-sig.pgp"));
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "expired_prim_uid_sig", &key));
+ assert_null(key);
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "non_prim_uid", &key));
+ assert_non_null(key);
+ uid_str = NULL;
+ assert_rnp_success(rnp_key_get_primary_uid(key, &uid_str));
+ assert_non_null(uid_str);
+ assert_string_equal(uid_str, "non_prim_uid");
+ rnp_buffer_destroy(uid_str);
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_false(valid);
+ rnp_uid_handle_destroy(uid);
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_uid_is_valid(uid, &valid));
+ assert_true(valid);
+ rnp_uid_handle_destroy(uid);
+ rnp_key_handle_destroy(key);
+
+ rnp_ffi_destroy(ffi);
+}
+
+TEST_F(rnp_tests, test_ffi_remove_uid)
+{
+ rnp_ffi_t ffi = NULL;
+ assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
+ assert_true(load_keys_gpg(ffi, "data/test_uid_validity/key-uids-pub.pgp"));
+
+ rnp_key_handle_t key = NULL;
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &key));
+ size_t count = 0;
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 4);
+ rnp_key_handle_t sub = NULL;
+ assert_rnp_success(rnp_key_get_subkey_at(key, 0, &sub));
+ rnp_uid_handle_t uid = NULL;
+ /* delete last userattr */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 3, &uid));
+ assert_rnp_failure(rnp_uid_remove(NULL, uid));
+ assert_rnp_failure(rnp_uid_remove(key, NULL));
+ assert_rnp_failure(rnp_uid_remove(sub, uid));
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 3);
+ /* delete uid in the middle, userid-expired */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ char *uidstr = NULL;
+ assert_rnp_success(rnp_key_get_uid_at(key, 1, &uidstr));
+ assert_string_equal(uidstr, "userid-expired");
+ rnp_buffer_destroy(uidstr);
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 2);
+ /* delete first uid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_key_get_uid_at(key, 0, &uidstr));
+ assert_string_equal(uidstr, "userid-valid");
+ rnp_buffer_destroy(uidstr);
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 1);
+ /* delete last and only uid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 0, &uid));
+ assert_rnp_success(rnp_key_get_uid_at(key, 0, &uidstr));
+ assert_string_equal(uidstr, "userid-invalid");
+ rnp_buffer_destroy(uidstr);
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 0);
+ rnp_key_handle_destroy(key);
+ rnp_key_handle_destroy(sub);
+ /* now let's reload pubring to make sure that they are removed */
+ reload_pubring(&ffi);
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &key));
+ assert_null(key);
+ assert_rnp_success(rnp_locate_key(ffi, "keyid", "f6e741d1df582d90", &key));
+ count = 255;
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 0);
+ rnp_key_handle_destroy(key);
+
+ /* delete userids of the secret key and reload */
+ assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
+ assert_true(load_keys_gpg(ffi,
+ "data/test_uid_validity/key-uids-pub.pgp",
+ "data/test_uid_validity/key-uids-sec.pgp"));
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &key));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 4);
+ bool secret = false;
+ assert_rnp_success(rnp_key_have_secret(key, &secret));
+ assert_true(secret);
+ /* remove userid-expired */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_key_get_uid_at(key, 1, &uidstr));
+ assert_string_equal(uidstr, "userid-expired");
+ rnp_buffer_destroy(uidstr);
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 3);
+ /* remove userid-invalid */
+ assert_rnp_success(rnp_key_get_uid_handle_at(key, 1, &uid));
+ assert_rnp_success(rnp_key_get_uid_at(key, 1, &uidstr));
+ assert_string_equal(uidstr, "userid-invalid");
+ rnp_buffer_destroy(uidstr);
+ assert_rnp_success(rnp_uid_remove(key, uid));
+ assert_rnp_success(rnp_uid_handle_destroy(uid));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 2);
+ rnp_key_handle_destroy(key);
+ /* reload */
+ reload_keyrings(&ffi);
+ assert_rnp_success(rnp_locate_key(ffi, "userid", "userid-valid", &key));
+ assert_rnp_success(rnp_key_get_uid_count(key, &count));
+ assert_int_equal(count, 2);
+ secret = false;
+ assert_rnp_success(rnp_key_have_secret(key, &secret));
+ assert_true(secret);
+ rnp_key_handle_destroy(key);
+
+ rnp_ffi_destroy(ffi);
+}