diff options
Diffstat (limited to 'src/tests/load-pgp.cpp')
-rw-r--r-- | src/tests/load-pgp.cpp | 985 |
1 files changed, 985 insertions, 0 deletions
diff --git a/src/tests/load-pgp.cpp b/src/tests/load-pgp.cpp new file mode 100644 index 0000000..560ed3d --- /dev/null +++ b/src/tests/load-pgp.cpp @@ -0,0 +1,985 @@ +/* + * 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 "../librekey/key_store_pgp.h" +#include "../librepgp/stream-packet.h" +#include "../librepgp/stream-sig.h" +#include "pgp-key.h" +#include "utils.h" + +#include "rnp_tests.h" +#include "support.h" + +/* This test loads a .gpg pubring with a single V3 key, + * and confirms that appropriate key flags are set. + */ +TEST_F(rnp_tests, test_load_v3_keyring_pgp) +{ + pgp_source_t src = {}; + + rnp_key_store_t *key_store = new rnp_key_store_t(global_ctx); + + // load pubring in to the key store + assert_rnp_success(init_file_src(&src, "data/keyrings/2/pubring.gpg")); + assert_rnp_success(rnp_key_store_pgp_read_from_src(key_store, &src)); + src_close(&src); + assert_int_equal(1, rnp_key_store_get_key_count(key_store)); + + // find the key by keyid + const pgp_key_t *key = rnp_tests_get_key_by_id(key_store, "DC70C124A50283F1"); + assert_non_null(key); + + // confirm the key flags are correct + assert_int_equal(key->flags(), + PGP_KF_ENCRYPT | PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH); + + // confirm that key expiration is correct + assert_int_equal(key->expiration(), 0); + + // cleanup + delete key_store; + + // load secret keyring and decrypt the key + key_store = new rnp_key_store_t(global_ctx); + + assert_rnp_success(init_file_src(&src, "data/keyrings/4/secring.pgp")); + assert_rnp_success(rnp_key_store_pgp_read_from_src(key_store, &src)); + src_close(&src); + assert_int_equal(1, rnp_key_store_get_key_count(key_store)); + + key = rnp_tests_get_key_by_id(key_store, "7D0BC10E933404C9"); + assert_non_null(key); + + // confirm the key flags are correct + assert_int_equal(key->flags(), + PGP_KF_ENCRYPT | PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH); + + // check if the key is secret and is locked + assert_true(key->is_secret()); + assert_true(key->is_locked()); + + // decrypt the key + pgp_key_pkt_t *seckey = pgp_decrypt_seckey_pgp(key->rawpkt(), key->pkt(), "password"); +#if defined(ENABLE_IDEA) + assert_non_null(seckey); +#else + assert_null(seckey); +#endif + + // cleanup + delete seckey; + delete key_store; +} + +/* This test loads a .gpg pubring with multiple V4 keys, + * finds a particular key of interest, and confirms that + * the appropriate key flags are set. + */ +TEST_F(rnp_tests, test_load_v4_keyring_pgp) +{ + pgp_source_t src = {}; + + rnp_key_store_t *key_store = new rnp_key_store_t(global_ctx); + + // load it in to the key store + assert_rnp_success(init_file_src(&src, "data/keyrings/1/pubring.gpg")); + assert_rnp_success(rnp_key_store_pgp_read_from_src(key_store, &src)); + src_close(&src); + assert_int_equal(7, rnp_key_store_get_key_count(key_store)); + + // find the key by keyid + static const std::string keyid = "8a05b89fad5aded1"; + const pgp_key_t * key = rnp_tests_get_key_by_id(key_store, keyid); + assert_non_null(key); + + // confirm the key flags are correct + assert_int_equal(key->flags(), PGP_KF_ENCRYPT); + + // cleanup + delete key_store; +} + +/* Just a helper for the below test */ +static void +check_pgp_keyring_counts(const char * path, + unsigned primary_count, + const unsigned subkey_counts[]) +{ + pgp_source_t src = {}; + rnp_key_store_t *key_store = new rnp_key_store_t(global_ctx); + + // load it in to the key store + assert_rnp_success(init_file_src(&src, path)); + assert_rnp_success(rnp_key_store_pgp_read_from_src(key_store, &src)); + src_close(&src); + + // count primary keys first + unsigned total_primary_count = 0; + for (auto &key : key_store->keys) { + if (key.is_primary()) { + total_primary_count++; + } + } + assert_int_equal(primary_count, total_primary_count); + + // now count subkeys in each primary key + unsigned total_subkey_count = 0; + unsigned primary = 0; + for (auto &key : key_store->keys) { + if (key.is_primary()) { + // check the subkey count for this primary key + assert_int_equal(key.subkey_count(), subkey_counts[primary++]); + } else if (key.is_subkey()) { + total_subkey_count++; + } + } + + // check the total (not really needed) + assert_int_equal(rnp_key_store_get_key_count(key_store), + total_primary_count + total_subkey_count); + + // cleanup + delete key_store; +} + +/* This test loads a pubring.gpg and secring.gpg and confirms + * that it contains the expected number of primary keys + * and the expected number of subkeys for each primary key. + */ +TEST_F(rnp_tests, test_load_keyring_and_count_pgp) +{ + unsigned int primary_count = 2; + unsigned int subkey_counts[2] = {3, 2}; + + // check pubring + check_pgp_keyring_counts("data/keyrings/1/pubring.gpg", primary_count, subkey_counts); + + // check secring + check_pgp_keyring_counts("data/keyrings/1/secring.gpg", primary_count, subkey_counts); +} + +/* This test loads a V4 keyring and confirms that certain + * bitfields and time fields are set correctly. + */ +TEST_F(rnp_tests, test_load_check_bitfields_and_times) +{ + const pgp_key_t * key; + const pgp_signature_t *sig = NULL; + + // load keyring + rnp_key_store_t *key_store = + new rnp_key_store_t(PGP_KEY_STORE_GPG, "data/keyrings/1/pubring.gpg", global_ctx); + assert_true(rnp_key_store_load_from_path(key_store, NULL)); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "7BC6709B15C23A4A"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 3); + // check subsig properties + for (size_t i = 0; i < key->sig_count(); i++) { + sig = &key->get_sig(i).sig; + static const time_t expected_creation_times[] = {1500569820, 1500569836, 1500569846}; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "7BC6709B15C23A4A")); + // check SS_CREATION_TIME + assert_int_equal(sig->creation(), expected_creation_times[i]); + // check SS_EXPIRATION_TIME + assert_int_equal(sig->expiration(), 0); + } + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 0); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "1ED63EE56FADC34D"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "7BC6709B15C23A4A")); + // check SS_CREATION_TIME [0] + assert_int_equal(sig->creation(), 1500569820); + assert_int_equal(sig->creation(), key->creation()); + // check SS_EXPIRATION_TIME [0] + assert_int_equal(sig->expiration(), 0); + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 0); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "1D7E8A5393C997A8"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "7BC6709B15C23A4A")); + // check SS_CREATION_TIME [0] + assert_int_equal(sig->creation(), 1500569851); + assert_int_equal(sig->creation(), key->creation()); + // check SS_EXPIRATION_TIME [0] + assert_int_equal(sig->expiration(), 0); + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 123 * 24 * 60 * 60 /* 123 days */); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "8A05B89FAD5ADED1"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "7BC6709B15C23A4A")); + // check SS_CREATION_TIME [0] + assert_int_equal(sig->creation(), 1500569896); + assert_int_equal(sig->creation(), key->creation()); + // check SS_EXPIRATION_TIME [0] + assert_int_equal(sig->expiration(), 0); + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 0); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "2FCADF05FFA501BB"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 3); + // check subsig properties + for (size_t i = 0; i < key->sig_count(); i++) { + sig = &key->get_sig(i).sig; + static const time_t expected_creation_times[] = {1501372449, 1500570153, 1500570147}; + + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "2FCADF05FFA501BB")); + // check SS_CREATION_TIME + assert_int_equal(sig->creation(), expected_creation_times[i]); + // check SS_EXPIRATION_TIME + assert_int_equal(sig->expiration(), 0); + } + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 2076663808); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "54505A936A4A970E"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "2FCADF05FFA501BB")); + // check SS_CREATION_TIME [0] + assert_int_equal(sig->creation(), 1500569946); + assert_int_equal(sig->creation(), key->creation()); + // check SS_EXPIRATION_TIME [0] + assert_int_equal(sig->expiration(), 0); + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 2076663808); + + // find + key = NULL; + key = rnp_tests_get_key_by_id(key_store, "326EF111425D14A5"); + assert_non_null(key); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check SS_ISSUER_KEY_ID + assert_true(cmp_keyid(sig->keyid(), "2FCADF05FFA501BB")); + // check SS_CREATION_TIME [0] + assert_int_equal(sig->creation(), 1500570165); + assert_int_equal(sig->creation(), key->creation()); + // check SS_EXPIRATION_TIME [0] + assert_int_equal(sig->expiration(), 0); + // check SS_KEY_EXPIRY + assert_int_equal(key->expiration(), 0); + + // cleanup + delete key_store; +} + +/* This test loads a V3 keyring and confirms that certain + * bitfields and time fields are set correctly. + */ +TEST_F(rnp_tests, test_load_check_bitfields_and_times_v3) +{ + pgp_key_id_t keyid = {}; + const pgp_key_t * key; + const pgp_signature_t *sig = NULL; + + // load keyring + rnp_key_store_t *key_store = + new rnp_key_store_t(PGP_KEY_STORE_GPG, "data/keyrings/2/pubring.gpg", global_ctx); + assert_true(rnp_key_store_load_from_path(key_store, NULL)); + + // find + key = NULL; + assert_true(rnp::hex_decode("DC70C124A50283F1", keyid.data(), keyid.size())); + key = rnp_tests_get_key_by_id(key_store, "DC70C124A50283F1"); + assert_non_null(key); + // check key version + assert_int_equal(key->version(), PGP_V3); + // check subsig count + assert_int_equal(key->sig_count(), 1); + sig = &key->get_sig(0).sig; + // check signature version + assert_int_equal(sig->version, 3); + // check issuer + assert_true(rnp::hex_decode("DC70C124A50283F1", keyid.data(), keyid.size())); + assert_true(keyid == sig->keyid()); + // check creation time + assert_int_equal(sig->creation(), 1005209227); + assert_int_equal(sig->creation(), key->creation()); + // check signature expiration time (V3 sigs have none) + assert_int_equal(sig->expiration(), 0); + // check key expiration + assert_int_equal(key->expiration(), 0); // only for V4 keys + assert_int_equal(key->pkt().v3_days, 0); + + // cleanup + delete key_store; +} + +#define MERGE_PATH "data/test_stream_key_merge/" + +TEST_F(rnp_tests, test_load_armored_pub_sec) +{ + rnp_key_store_t *key_store = + new rnp_key_store_t(PGP_KEY_STORE_GPG, MERGE_PATH "key-both.asc", global_ctx); + assert_true(rnp_key_store_load_from_path(key_store, NULL)); + + /* we must have 1 main key and 2 subkeys */ + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + + pgp_key_t *key = NULL; + assert_non_null(key = rnp_tests_get_key_by_id(key_store, "9747D2A6B3A63124")); + assert_true(key->valid()); + assert_true(key->is_primary()); + assert_true(key->is_secret()); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_SECRET_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + + assert_non_null(key = rnp_tests_get_key_by_id(key_store, "AF1114A47F5F5B28")); + assert_true(key->valid()); + assert_true(key->is_subkey()); + assert_true(key->is_secret()); + assert_int_equal(key->rawpkt_count(), 2); + assert_int_equal(key->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + + assert_non_null(key = rnp_tests_get_key_by_id(key_store, "16CD16F267CCDD4F")); + assert_true(key->valid()); + assert_true(key->is_subkey()); + assert_true(key->is_secret()); + assert_int_equal(key->rawpkt_count(), 2); + assert_int_equal(key->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + + /* make sure half of keyid doesn't work */ + assert_null(key = rnp_tests_get_key_by_id(key_store, "0000000016CD16F2")); + assert_null(key = rnp_tests_get_key_by_id(key_store, "67CCDD4F00000000")); + assert_null(key = rnp_tests_get_key_by_id(key_store, "0000000067CCDD4F")); + + /* both user ids should be present */ + assert_non_null(rnp_tests_key_search(key_store, "key-merge-uid-1")); + assert_non_null(rnp_tests_key_search(key_store, "key-merge-uid-2")); + + delete key_store; +} + +static bool +load_transferable_key(pgp_transferable_key_t *key, const char *fname) +{ + pgp_source_t src = {}; + bool res = !init_file_src(&src, fname) && !process_pgp_key(src, *key, false); + src_close(&src); + return res; +} + +static bool +load_transferable_subkey(pgp_transferable_subkey_t *key, const char *fname) +{ + pgp_source_t src = {}; + bool res = !init_file_src(&src, fname) && !process_pgp_subkey(src, *key, false); + src_close(&src); + return res; +} + +static bool +load_keystore(rnp_key_store_t *keystore, const char *fname) +{ + pgp_source_t src = {}; + bool res = !init_file_src(&src, fname) && !rnp_key_store_pgp_read_from_src(keystore, &src); + src_close(&src); + return res; +} + +static bool +check_subkey_fp(pgp_key_t *key, pgp_key_t *subkey, size_t index) +{ + if (key->get_subkey_fp(index) != subkey->fp()) { + return false; + } + if (!subkey->has_primary_fp()) { + return false; + } + return key->fp() == subkey->primary_fp(); +} + +TEST_F(rnp_tests, test_load_merge) +{ + pgp_key_t * key, *skey1, *skey2; + pgp_transferable_key_t tkey = {}; + pgp_transferable_subkey_t tskey = {}; + pgp_password_provider_t provider = {}; + provider.callback = string_copy_password_callback; + provider.userdata = (void *) "password"; + + rnp_key_store_t *key_store = new rnp_key_store_t(PGP_KEY_STORE_GPG, "", global_ctx); + std::string keyid = "9747D2A6B3A63124"; + std::string sub1id = "AF1114A47F5F5B28"; + std::string sub2id = "16CD16F267CCDD4F"; + + /* load just key packet */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-just-key.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 1); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_false(key->valid()); + assert_int_equal(key->rawpkt_count(), 1); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + + /* load key + user id 1 without sigs */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-uid-1-no-sigs.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 1); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_false(key->valid()); + assert_int_equal(key->uid_count(), 1); + assert_int_equal(key->rawpkt_count(), 2); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_null(rnp_tests_key_search(key_store, "key-merge-uid-1")); + assert_true(key == rnp_tests_get_key_by_id(key_store, "9747D2A6B3A63124")); + + /* load key + user id 1 with sigs */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-uid-1.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 1); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_true(key->valid()); + assert_int_equal(key->uid_count(), 1); + assert_int_equal(key->rawpkt_count(), 3); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_true(key == rnp_tests_key_search(key_store, "key-merge-uid-1")); + + /* load key + user id 2 with sigs */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-uid-2.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + /* try to add it twice */ + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 1); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_true(key->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_true(key == rnp_tests_key_search(key_store, "key-merge-uid-1")); + assert_true(key == rnp_tests_key_search(key_store, "key-merge-uid-2")); + + /* load key + subkey 1 without sigs */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-subkey-1-no-sigs.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 2); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_true(key->valid()); + assert_false(skey1->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->subkey_count(), 1); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey1->uid_count(), 0); + assert_int_equal(skey1->rawpkt_count(), 1); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + + /* load just subkey 1 but with signature */ + assert_true(load_transferable_subkey(&tskey, MERGE_PATH "key-pub-no-key-subkey-1.pgp")); + assert_true(rnp_key_store_add_transferable_subkey(key_store, &tskey, key)); + /* try to add it twice */ + assert_true(rnp_key_store_add_transferable_subkey(key_store, &tskey, key)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 2); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_true(key->valid()); + assert_true(skey1->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->subkey_count(), 1); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey1->uid_count(), 0); + assert_int_equal(skey1->rawpkt_count(), 2); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_int_equal(skey1->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + + /* load key + subkey 2 with signature */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub-subkey-2.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + /* try to add it twice */ + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_non_null(skey2 = rnp_tests_get_key_by_id(key_store, sub2id)); + assert_true(key->valid()); + assert_true(skey1->valid()); + assert_true(skey2->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->subkey_count(), 2); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_true(check_subkey_fp(key, skey2, 1)); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey1->uid_count(), 0); + assert_int_equal(skey1->rawpkt_count(), 2); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_int_equal(skey1->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey2->uid_count(), 0); + assert_int_equal(skey2->rawpkt_count(), 2); + assert_int_equal(skey2->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_int_equal(skey2->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + + /* load secret key & subkeys */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-sec-no-uid-no-sigs.pgp")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + /* try to add it twice */ + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_non_null(skey2 = rnp_tests_get_key_by_id(key_store, sub2id)); + assert_true(key->valid()); + assert_true(skey1->valid()); + assert_true(skey2->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->subkey_count(), 2); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_true(check_subkey_fp(key, skey2, 1)); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_SECRET_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey1->uid_count(), 0); + assert_int_equal(skey1->rawpkt_count(), 2); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(skey1->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey2->uid_count(), 0); + assert_int_equal(skey2->rawpkt_count(), 2); + assert_int_equal(skey2->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(skey2->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + + assert_true(key->unlock(provider)); + assert_true(skey1->unlock(provider)); + assert_true(skey2->unlock(provider)); + + /* load the whole public + secret key */ + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-pub.asc")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_true(load_transferable_key(&tkey, MERGE_PATH "key-sec.asc")); + assert_true(rnp_key_store_add_transferable_key(key_store, &tkey)); + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_non_null(skey2 = rnp_tests_get_key_by_id(key_store, sub2id)); + assert_true(key->valid()); + assert_true(skey1->valid()); + assert_true(skey2->valid()); + assert_int_equal(key->uid_count(), 2); + assert_int_equal(key->subkey_count(), 2); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_true(check_subkey_fp(key, skey2, 1)); + assert_int_equal(key->rawpkt_count(), 5); + assert_int_equal(key->rawpkt().tag, PGP_PKT_SECRET_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(key->get_uid(1).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(1).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey1->uid_count(), 0); + assert_int_equal(skey1->rawpkt_count(), 2); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(skey1->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_int_equal(skey2->uid_count(), 0); + assert_int_equal(skey2->rawpkt_count(), 2); + assert_int_equal(skey2->rawpkt().tag, PGP_PKT_SECRET_SUBKEY); + assert_int_equal(skey2->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_true(key == rnp_tests_key_search(key_store, "key-merge-uid-1")); + assert_true(key == rnp_tests_key_search(key_store, "key-merge-uid-2")); + + delete key_store; +} + +TEST_F(rnp_tests, test_load_public_from_secret) +{ + rnp_key_store_t *secstore = + new rnp_key_store_t(PGP_KEY_STORE_GPG, MERGE_PATH "key-sec.asc", global_ctx); + assert_true(rnp_key_store_load_from_path(secstore, NULL)); + rnp_key_store_t *pubstore = + new rnp_key_store_t(PGP_KEY_STORE_GPG, "pubring.gpg", global_ctx); + + std::string keyid = "9747D2A6B3A63124"; + std::string sub1id = "AF1114A47F5F5B28"; + std::string sub2id = "16CD16F267CCDD4F"; + + pgp_key_t *key = NULL, *skey1 = NULL, *skey2 = NULL; + assert_non_null(key = rnp_tests_get_key_by_id(secstore, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(secstore, sub1id)); + assert_non_null(skey2 = rnp_tests_get_key_by_id(secstore, sub2id)); + + /* copy the secret key */ + pgp_key_t keycp = pgp_key_t(*key, false); + assert_true(keycp.is_secret()); + assert_int_equal(keycp.subkey_count(), 2); + assert_true(keycp.get_subkey_fp(0) == skey1->fp()); + assert_true(keycp.get_subkey_fp(1) == skey2->fp()); + assert_true(keycp.grip() == key->grip()); + assert_int_equal(keycp.rawpkt().tag, PGP_PKT_SECRET_KEY); + + /* copy the public part */ + keycp = pgp_key_t(*key, true); + assert_false(keycp.is_secret()); + assert_int_equal(keycp.subkey_count(), 2); + assert_true(check_subkey_fp(&keycp, skey1, 0)); + assert_true(check_subkey_fp(&keycp, skey2, 1)); + assert_true(keycp.grip() == key->grip()); + assert_int_equal(keycp.rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_null(keycp.pkt().sec_data); + assert_int_equal(keycp.pkt().sec_len, 0); + assert_false(keycp.pkt().material.secret); + rnp_key_store_add_key(pubstore, &keycp); + /* subkey 1 */ + keycp = pgp_key_t(*skey1, true); + assert_false(keycp.is_secret()); + assert_int_equal(keycp.subkey_count(), 0); + assert_true(check_subkey_fp(key, &keycp, 0)); + assert_true(keycp.grip() == skey1->grip()); + assert_true(cmp_keyid(keycp.keyid(), sub1id)); + assert_int_equal(keycp.rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_null(keycp.pkt().sec_data); + assert_int_equal(keycp.pkt().sec_len, 0); + assert_false(keycp.pkt().material.secret); + rnp_key_store_add_key(pubstore, &keycp); + /* subkey 2 */ + keycp = pgp_key_t(*skey2, true); + assert_false(keycp.is_secret()); + assert_int_equal(keycp.subkey_count(), 0); + assert_true(check_subkey_fp(key, &keycp, 1)); + assert_true(keycp.grip() == skey2->grip()); + assert_true(cmp_keyid(keycp.keyid(), sub2id)); + assert_int_equal(keycp.rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_null(keycp.pkt().sec_data); + assert_int_equal(keycp.pkt().sec_len, 0); + assert_false(keycp.pkt().material.secret); + rnp_key_store_add_key(pubstore, &keycp); + /* save pubring */ + assert_true(rnp_key_store_write_to_path(pubstore)); + delete pubstore; + /* reload */ + pubstore = new rnp_key_store_t(PGP_KEY_STORE_GPG, "pubring.gpg", global_ctx); + assert_true(rnp_key_store_load_from_path(pubstore, NULL)); + assert_non_null(key = rnp_tests_get_key_by_id(pubstore, keyid)); + assert_non_null(skey1 = rnp_tests_get_key_by_id(pubstore, sub1id)); + assert_non_null(skey2 = rnp_tests_get_key_by_id(pubstore, sub2id)); + + delete pubstore; + delete secstore; +} + +TEST_F(rnp_tests, test_key_import) +{ + cli_rnp_t rnp = {}; + pgp_transferable_key_t tkey = {}; + pgp_transferable_subkey_t *tskey = NULL; + pgp_transferable_userid_t *tuid = NULL; + + assert_int_equal(RNP_MKDIR(".rnp", S_IRWXU), 0); + assert_true(setup_cli_rnp_common(&rnp, RNP_KEYSTORE_GPG, ".rnp", NULL)); + + /* import just the public key */ + rnp_cfg &cfg = rnp.cfg(); + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-pub-just-key.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + size_t keycount = 0; + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 1); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 0); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_true(tkey.subkeys.empty()); + assert_true(tkey.signatures.empty()); + assert_true(tkey.userids.empty()); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + + /* import public key + 1 userid */ + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-pub-uid-1-no-sigs.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 1); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 0); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_true(tkey.subkeys.empty()); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 1); + assert_non_null(tuid = &tkey.userids.front()); + assert_true(tuid->signatures.empty()); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + + /* import public key + 1 userid + signature */ + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-pub-uid-1.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 1); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 0); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_true(tkey.subkeys.empty()); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 1); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + + /* import public key + 1 subkey */ + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-pub-subkey-1.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 2); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 0); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_int_equal(tkey.subkeys.size(), 1); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 1); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tskey = &tkey.subkeys.front()); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_PUBLIC_SUBKEY); + + /* import secret key with 1 uid and 1 subkey */ + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-sec-uid-1-subkey-1.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 2); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 2); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_int_equal(tkey.subkeys.size(), 1); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 1); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tskey = &tkey.subkeys.front()); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_PUBLIC_SUBKEY); + + assert_true(load_transferable_key(&tkey, ".rnp/secring.gpg")); + assert_int_equal(tkey.subkeys.size(), 1); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 1); + assert_int_equal(tkey.key.tag, PGP_PKT_SECRET_KEY); + assert_rnp_success(decrypt_secret_key(&tkey.key, "password")); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tskey = &tkey.subkeys.front()); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_SECRET_SUBKEY); + assert_rnp_success(decrypt_secret_key(&tskey->subkey, "password")); + + /* import secret key with 2 uids and 2 subkeys */ + cfg.set_str(CFG_KEYFILE, MERGE_PATH "key-sec.pgp"); + assert_true(cli_rnp_add_key(&rnp)); + assert_true(cli_rnp_save_keyrings(&rnp)); + assert_rnp_success(rnp_get_public_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 3); + assert_rnp_success(rnp_get_secret_key_count(rnp.ffi, &keycount)); + assert_int_equal(keycount, 3); + + assert_true(load_transferable_key(&tkey, ".rnp/pubring.gpg")); + assert_int_equal(tkey.subkeys.size(), 2); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 2); + assert_int_equal(tkey.key.tag, PGP_PKT_PUBLIC_KEY); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tuid = &tkey.userids[1]); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-2", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tskey = &tkey.subkeys.front()); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_PUBLIC_SUBKEY); + assert_non_null(tskey = &tkey.subkeys[1]); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_PUBLIC_SUBKEY); + + assert_true(load_transferable_key(&tkey, ".rnp/secring.gpg")); + assert_int_equal(tkey.subkeys.size(), 2); + assert_true(tkey.signatures.empty()); + assert_int_equal(tkey.userids.size(), 2); + assert_int_equal(tkey.key.tag, PGP_PKT_SECRET_KEY); + assert_rnp_success(decrypt_secret_key(&tkey.key, "password")); + assert_non_null(tuid = &tkey.userids.front()); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-1", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tuid = &tkey.userids[1]); + assert_int_equal(tuid->signatures.size(), 1); + assert_false(memcmp(tuid->uid.uid, "key-merge-uid-2", 15)); + assert_int_equal(tuid->uid.tag, PGP_PKT_USER_ID); + assert_non_null(tskey = &tkey.subkeys.front()); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_SECRET_SUBKEY); + assert_rnp_success(decrypt_secret_key(&tskey->subkey, "password")); + assert_non_null(tskey = &tkey.subkeys[1]); + assert_int_equal(tskey->signatures.size(), 1); + assert_int_equal(tskey->subkey.tag, PGP_PKT_SECRET_SUBKEY); + assert_rnp_success(decrypt_secret_key(&tskey->subkey, "password")); + + rnp.end(); +} + +TEST_F(rnp_tests, test_load_subkey) +{ + rnp_key_store_t *key_store = new rnp_key_store_t(PGP_KEY_STORE_GPG, "", global_ctx); + std::string keyid = "9747D2A6B3A63124"; + std::string sub1id = "AF1114A47F5F5B28"; + std::string sub2id = "16CD16F267CCDD4F"; + + /* load first subkey with signature */ + pgp_key_t *key = NULL, *skey1 = NULL, *skey2 = NULL; + assert_true(load_keystore(key_store, MERGE_PATH "key-pub-just-subkey-1.pgp")); + assert_int_equal(rnp_key_store_get_key_count(key_store), 1); + assert_non_null(skey1 = rnp_tests_get_key_by_id(key_store, sub1id)); + assert_false(skey1->valid()); + assert_int_equal(skey1->rawpkt_count(), 2); + assert_int_equal(skey1->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_int_equal(skey1->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_false(skey1->has_primary_fp()); + + /* load second subkey, without signature */ + assert_true(load_keystore(key_store, MERGE_PATH "key-pub-just-subkey-2-no-sigs.pgp")); + assert_int_equal(rnp_key_store_get_key_count(key_store), 2); + assert_non_null(skey2 = rnp_tests_get_key_by_id(key_store, sub2id)); + assert_false(skey2->valid()); + assert_int_equal(skey2->rawpkt_count(), 1); + assert_int_equal(skey2->rawpkt().tag, PGP_PKT_PUBLIC_SUBKEY); + assert_false(skey2->has_primary_fp()); + assert_false(skey1 == skey2); + + /* load primary key without subkey signatures */ + assert_true(load_keystore(key_store, MERGE_PATH "key-pub-uid-1.pgp")); + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + assert_non_null(key = rnp_tests_get_key_by_id(key_store, keyid)); + assert_true(key->valid()); + assert_int_equal(key->rawpkt_count(), 3); + assert_int_equal(key->rawpkt().tag, PGP_PKT_PUBLIC_KEY); + assert_int_equal(key->get_uid(0).rawpkt.tag, PGP_PKT_USER_ID); + assert_int_equal(key->get_sig(0).rawpkt.tag, PGP_PKT_SIGNATURE); + assert_true(skey1 == rnp_tests_get_key_by_id(key_store, sub1id)); + assert_true(skey2 == rnp_tests_get_key_by_id(key_store, sub2id)); + assert_true(skey1->has_primary_fp()); + assert_true(check_subkey_fp(key, skey1, 0)); + assert_int_equal(key->subkey_count(), 1); + assert_true(skey1->valid()); + assert_false(skey2->valid()); + + /* load second subkey with signature */ + assert_true(load_keystore(key_store, MERGE_PATH "key-pub-just-subkey-2.pgp")); + assert_int_equal(rnp_key_store_get_key_count(key_store), 3); + assert_true(key == rnp_tests_get_key_by_id(key_store, keyid)); + assert_true(skey1 == rnp_tests_get_key_by_id(key_store, sub1id)); + assert_true(skey2 == rnp_tests_get_key_by_id(key_store, sub2id)); + assert_true(skey2->has_primary_fp()); + assert_true(check_subkey_fp(key, skey2, 1)); + assert_int_equal(key->subkey_count(), 2); + assert_true(skey2->valid()); + + delete key_store; +} |