/* * Copyright (c) 2017-2019 [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 "../librekey/key_store_pgp.h" #include "pgp-key.h" #include "rnp_tests.h" #include "support.h" /* This test loads a pgp keyring and adds a few userids to the key. */ TEST_F(rnp_tests, test_key_add_userid) { pgp_key_t * key = NULL; pgp_source_t src = {}; pgp_dest_t dst = {}; const uint32_t base_expiry = 1234567890; static const char *keyids[] = {"7bc6709b15c23a4a", // primary "1ed63ee56fadc34d", "1d7e8a5393c997a8", "8a05b89fad5aded1", "2fcadf05ffa501bb", // primary "54505a936a4a970e", "326ef111425d14a5"}; rnp_key_store_t *ks = new rnp_key_store_t(global_ctx); assert_rnp_success(init_file_src(&src, "data/keyrings/1/secring.gpg")); assert_rnp_success(rnp_key_store_pgp_read_from_src(ks, &src)); src_close(&src); // locate our key assert_non_null(key = rnp_tests_get_key_by_id(ks, keyids[0])); assert_non_null(key); // unlock the key pgp_password_provider_t pprov(string_copy_password_callback, (void *) "password"); assert_true(key->unlock(pprov)); // save the counts for a few items unsigned uidc = key->uid_count(); unsigned subsigc = key->sig_count(); // add first, non-primary userid rnp_selfsig_cert_info_t selfsig0; selfsig0.userid = "added0"; selfsig0.key_flags = 0x2; selfsig0.key_expiration = base_expiry; selfsig0.primary = false; auto curtime = global_ctx.time(); global_ctx.set_time(curtime > SHA1_KEY_FROM ? SHA1_KEY_FROM - 100 : 0); key->add_uid_cert(selfsig0, PGP_HASH_SHA1, global_ctx); // attempt to add sha1-signed uid and make sure it succeeds now and fails after the cutoff // date in 2024 assert_int_equal(base_expiry, key->expiration()); assert_int_equal(0x2, key->flags()); assert_true(key->get_uid(uidc).valid); // delete new uid and add one in the future key->del_uid(uidc); global_ctx.set_time(SHA1_KEY_FROM + 2); key->add_uid_cert(selfsig0, PGP_HASH_SHA1, global_ctx); assert_int_equal(0, key->expiration()); assert_int_equal(0x3, key->flags()); assert_false(key->get_uid(uidc).valid); global_ctx.set_time(0); key->del_uid(uidc); assert_int_equal(uidc, key->uid_count()); assert_int_equal(subsigc, key->sig_count()); key->add_uid_cert(selfsig0, PGP_HASH_SHA256, global_ctx); // make sure this userid has not been marked as primary assert_false(key->has_primary_uid()); // make sure key expiration and flags are set assert_int_equal(base_expiry, key->expiration()); assert_int_equal(0x2, key->flags()); assert_true(key->get_uid(uidc).valid); // add a primary userid rnp_selfsig_cert_info_t selfsig1; selfsig1.userid = "added1"; selfsig1.key_flags = 0xAB; selfsig1.key_expiration = base_expiry + 1; selfsig1.primary = 1; key->add_uid_cert(selfsig1, PGP_HASH_SHA256, global_ctx); // make sure this userid has been marked as primary assert_int_equal(key->uid_count() - 1, key->get_primary_uid()); // make sure key expiration and flags are set assert_int_equal(base_expiry + 1, key->expiration()); assert_int_equal(0xAB, key->flags()); assert_true(key->get_uid(uidc + 1).valid); // try to add the same userid (should fail) rnp_selfsig_cert_info_t dup_selfsig; dup_selfsig.userid = "added1"; assert_throw(key->add_uid_cert(dup_selfsig, PGP_HASH_SHA256, global_ctx)); // try to add another primary userid (should fail) rnp_selfsig_cert_info_t selfsig2; selfsig2.userid = "added2"; selfsig2.primary = 1; assert_throw(key->add_uid_cert(selfsig2, PGP_HASH_SHA256, global_ctx)); selfsig2.userid = "added2"; selfsig2.key_flags = 0xCD; selfsig2.primary = 0; // actually add another userid key->add_uid_cert(selfsig2, PGP_HASH_SHA256, global_ctx); // confirm that the counts have increased as expected assert_int_equal(key->uid_count(), uidc + 3); assert_int_equal(key->sig_count(), subsigc + 3); assert_true(key->get_uid(uidc + 2).valid); // make sure key expiration and flags are not updated as they are picked from the primary assert_int_equal(base_expiry + 1, key->expiration()); assert_int_equal(0xAB, key->flags()); // check the userids array // added0 assert_string_equal(key->get_uid(uidc).str.c_str(), "added0"); assert_int_equal(uidc, key->get_sig(subsigc).uid); assert_int_equal(0x2, key->get_sig(subsigc).key_flags); // added1 assert_string_equal(key->get_uid(uidc + 1).str.c_str(), "added1"); assert_int_equal(uidc + 1, key->get_sig(subsigc + 1).uid); assert_int_equal(0xAB, key->get_sig(subsigc + 1).key_flags); // added2 assert_string_equal(key->get_uid(uidc + 2).str.c_str(), "added2"); assert_int_equal(uidc + 2, key->get_sig(subsigc + 2).uid); assert_int_equal(0xCD, key->get_sig(subsigc + 2).key_flags); // save the raw packets for the key (to reload later) assert_rnp_success(init_mem_dest(&dst, NULL, 0)); key->write(dst); // cleanup delete ks; key = NULL; // start over ks = new rnp_key_store_t(global_ctx); assert_non_null(ks); // read from the saved packets assert_rnp_success(init_mem_src(&src, mem_dest_get_memory(&dst), dst.writeb, false)); assert_rnp_success(rnp_key_store_pgp_read_from_src(ks, &src)); src_close(&src); dst_close(&dst, true); assert_non_null(key = rnp_tests_get_key_by_id(ks, keyids[0])); // confirm that the counts have increased as expected assert_int_equal(key->uid_count(), uidc + 3); assert_int_equal(key->sig_count(), subsigc + 3); // make sure correct key expiration and flags are set assert_int_equal(base_expiry + 1, key->expiration()); assert_int_equal(0xAB, key->flags()); // check the userids array // added0 assert_string_equal(key->get_uid(uidc).str.c_str(), "added0"); assert_int_equal(uidc, key->get_sig(subsigc).uid); assert_int_equal(0x2, key->get_sig(subsigc).key_flags); assert_true(key->get_uid(uidc).valid); // added1 assert_string_equal(key->get_uid(uidc + 1).str.c_str(), "added1"); assert_int_equal(uidc + 1, key->get_sig(subsigc + 1).uid); assert_int_equal(0xAB, key->get_sig(subsigc + 1).key_flags); assert_true(key->get_uid(uidc + 1).valid); // added2 assert_string_equal(key->get_uid(uidc + 2).str.c_str(), "added2"); assert_int_equal(uidc + 2, key->get_sig(subsigc + 2).uid); assert_int_equal(0xCD, key->get_sig(subsigc + 2).key_flags); assert_true(key->get_uid(uidc + 2).valid); // delete primary userid and see how flags/expiration changes key->del_uid(uidc + 1); key->revalidate(*ks); assert_string_equal(key->get_uid(uidc + 1).str.c_str(), "added2"); assert_int_equal(uidc + 1, key->get_sig(subsigc + 1).uid); assert_int_equal(0xCD, key->get_sig(subsigc + 1).key_flags); assert_int_equal(key->expiration(), 0); assert_int_equal(key->flags(), 0xCD); // delete first uid key->del_uid(0); key->revalidate(*ks); assert_string_equal(key->get_uid(uidc).str.c_str(), "added2"); assert_int_equal(uidc, key->get_sig(subsigc).uid); assert_int_equal(0xCD, key->get_sig(subsigc).key_flags); assert_int_equal(key->expiration(), 0); assert_int_equal(key->flags(), 0xCD); // delete last uid, leaving added0 only key->del_uid(uidc); key->revalidate(*ks); assert_string_equal(key->get_uid(uidc - 1).str.c_str(), "added0"); assert_int_equal(uidc - 1, key->get_sig(subsigc - 1).uid); assert_int_equal(0x2, key->get_sig(subsigc - 1).key_flags); assert_int_equal(key->expiration(), base_expiry); assert_int_equal(key->flags(), 0x2); // delete added0 key->del_uid(0); key->revalidate(*ks); // cleanup delete ks; }