1.1 --- a/src/key_reset.c Thu Jan 09 09:19:36 2020 +0100
1.2 +++ b/src/key_reset.c Thu Jan 09 22:02:58 2020 +0100
1.3 @@ -895,96 +895,94 @@
1.4
1.5 if (is_own_private) {
1.6
1.7 - // If there's no address, we want to reset this key for every identity
1.8 - // it's a part of. Since this means generating new keys, we have to
1.9 - // grab all the identities associated with it.
1.10 - if (EMPTYSTR(tmp_ident->address)) {
1.11 - status = get_identities_by_main_key_id(session, fpr_copy, &key_idents);
1.12 -
1.13 - if (status != PEP_CANNOT_FIND_IDENTITY) {
1.14 - if (status == PEP_STATUS_OK) {
1.15 - // now have ident list, or should
1.16 - identity_list* curr_ident;
1.17 -
1.18 - bool is_grouped = false;
1.19 - if (!deviceGrouped(session, &is_grouped)) {
1.20 - for (curr_ident = key_idents; curr_ident && curr_ident->ident;
1.21 - curr_ident = curr_ident->next) {
1.22 -
1.23 - pEp_identity* this_identity = curr_ident->ident;
1.24 - // Do the full reset on this identity
1.25 - status = key_reset(session, fpr_copy, this_identity);
1.26 -
1.27 - // Ident list gets freed below, do not free here!
1.28 - }
1.29 - }
1.30 - else {
1.31 - status = _key_reset_device_group_for_shared_key(session, key_idents, fpr_copy); }
1.32 - }
1.33 - // Ok, we've either now reset for each own identity with this key, or
1.34 - // we got an error and want to bail anyway.
1.35 - goto pEp_free;
1.36 - }
1.37 - else
1.38 - return PEP_CANNOT_FIND_IDENTITY;
1.39 - }
1.40 + // This is now the "is_own" base case - we don't do this
1.41 + // per-identity, because all identities using this key will
1.42 + // need new ones. That said, this is really only a problem
1.43 + // with manual key management, something which we only support
1.44 + // to a limited extent in any event.
1.45
1.46 -
1.47 - // Ok, first we generate a new key.
1.48 -
1.49 - // Base case for is_own_private starts here
1.50 - // tmp ident is an actual identity now (not just a skeleton?)
1.51 - status = revoke_key(session, fpr_copy, NULL);
1.52 + bool is_grouped = false;
1.53 + status = deviceGrouped(session, &is_grouped);
1.54 +
1.55 + // Regardless of the single identity this is for, for own keys, we do this
1.56 + // for all keys associated with the identity.
1.57 + status = get_identities_by_main_key_id(session, fpr_copy, &key_idents);
1.58
1.59 - // If we have a full identity, we have some cleanup and generation tasks here
1.60 - if (!EMPTYSTR(tmp_ident->address)) {
1.61 - // generate new key
1.62 - if (status == PEP_STATUS_OK) {
1.63 - tmp_ident->fpr = NULL;
1.64 - status = myself(session, tmp_ident);
1.65 - }
1.66 - if (status == PEP_STATUS_OK && tmp_ident->fpr && strcmp(fpr_copy, tmp_ident->fpr) != 0)
1.67 - new_key = strdup(tmp_ident->fpr);
1.68 - // Error handling?
1.69 -
1.70 - // mistrust fpr from trust
1.71 - tmp_ident->fpr = fpr_copy;
1.72 -
1.73 - tmp_ident->comm_type = PEP_ct_mistrusted;
1.74 - status = set_trust(session, tmp_ident);
1.75 - tmp_ident->fpr = NULL;
1.76 -
1.77 - // Done with old use of ident.
1.78 - if (status == PEP_STATUS_OK) {
1.79 - // Update fpr for outgoing
1.80 - status = myself(session, tmp_ident);
1.81 + if (status != PEP_CANNOT_FIND_IDENTITY) {
1.82 + if (is_grouped)
1.83 + status = _key_reset_device_group_for_shared_key(session, key_idents, fpr_copy);
1.84 + else if (status == PEP_STATUS_OK) {
1.85 + // now have ident list, or should
1.86 + identity_list* curr_ident;
1.87 +
1.88 + for (curr_ident = key_idents; curr_ident && curr_ident->ident;
1.89 + curr_ident = curr_ident->next) {
1.90 +
1.91 + pEp_identity* this_identity = curr_ident->ident;
1.92 +
1.93 + // Do the full reset on this identity
1.94 + // Base case for is_own_private starts here
1.95 + // tmp ident is an actual identity now (not just a skeleton?)
1.96 + status = revoke_key(session, fpr_copy, NULL);
1.97 +
1.98 + // If we have a full identity, we have some cleanup and generation tasks here
1.99 + if (!EMPTYSTR(tmp_ident->address)) {
1.100 + // generate new key
1.101 + if (status == PEP_STATUS_OK) {
1.102 + tmp_ident->fpr = NULL;
1.103 + status = myself(session, tmp_ident);
1.104 + }
1.105 + if (status == PEP_STATUS_OK && tmp_ident->fpr && strcmp(fpr_copy, tmp_ident->fpr) != 0)
1.106 + new_key = strdup(tmp_ident->fpr);
1.107 + // Error handling?
1.108 +
1.109 + // mistrust fpr from trust
1.110 + tmp_ident->fpr = fpr_copy;
1.111 +
1.112 + tmp_ident->comm_type = PEP_ct_mistrusted;
1.113 + status = set_trust(session, tmp_ident);
1.114 + tmp_ident->fpr = NULL;
1.115 +
1.116 + // Done with old use of ident.
1.117 + if (status == PEP_STATUS_OK) {
1.118 + // Update fpr for outgoing
1.119 + status = myself(session, tmp_ident);
1.120 + }
1.121 + }
1.122 +
1.123 + if (status == PEP_STATUS_OK)
1.124 + // cascade that mistrust for anyone using this key
1.125 + status = mark_as_compromised(session, fpr_copy);
1.126 +
1.127 + if (status == PEP_STATUS_OK)
1.128 + status = remove_fpr_as_default(session, fpr_copy);
1.129 + if (status == PEP_STATUS_OK)
1.130 + status = add_mistrusted_key(session, fpr_copy);
1.131 +
1.132 + // If there's a new key, do the DB linkage with the revoked one, and
1.133 + // send the key reset mail opportunistically to recently contacted
1.134 + // partners
1.135 + if (new_key) {
1.136 + // add to revocation list
1.137 + if (status == PEP_STATUS_OK)
1.138 + status = set_revoked(session, fpr_copy, new_key, time(NULL));
1.139 + // for all active communication partners:
1.140 + // active_send revocation
1.141 +
1.142 + tmp_ident->fpr = fpr_copy;
1.143 + if (status == PEP_STATUS_OK)
1.144 + status = send_key_reset_to_recents(session, tmp_ident, fpr_copy, new_key);
1.145 + tmp_ident->fpr = NULL;
1.146 + }
1.147 + // Ident list gets freed below, do not free here!
1.148 + }
1.149 }
1.150 - }
1.151 -
1.152 - if (status == PEP_STATUS_OK)
1.153 - // cascade that mistrust for anyone using this key
1.154 - status = mark_as_compromised(session, fpr_copy);
1.155 -
1.156 - if (status == PEP_STATUS_OK)
1.157 - status = remove_fpr_as_default(session, fpr_copy);
1.158 - if (status == PEP_STATUS_OK)
1.159 - status = add_mistrusted_key(session, fpr_copy);
1.160 -
1.161 - // If there's a new key, do the DB linkage with the revoked one, and
1.162 - // send the key reset mail opportunistically to recently contacted
1.163 - // partners
1.164 - if (new_key) {
1.165 - // add to revocation list
1.166 - if (status == PEP_STATUS_OK)
1.167 - status = set_revoked(session, fpr_copy, new_key, time(NULL));
1.168 - // for all active communication partners:
1.169 - // active_send revocation
1.170 -
1.171 - tmp_ident->fpr = fpr_copy;
1.172 - if (status == PEP_STATUS_OK)
1.173 - status = send_key_reset_to_recents(session, tmp_ident, fpr_copy, new_key);
1.174 - tmp_ident->fpr = NULL;
1.175 - }
1.176 + // Ok, we've either now reset for each own identity with this key, or
1.177 + // we got an error and want to bail anyway.
1.178 + goto pEp_free;
1.179 + }
1.180 + else
1.181 + return PEP_CANNOT_FIND_IDENTITY;
1.182 } // end is_own_private
1.183 else {
1.184 // if it's mistrusted, make it not be so.
2.1 --- a/test/src/KeyResetMessageTest.cc Thu Jan 09 09:19:36 2020 +0100
2.2 +++ b/test/src/KeyResetMessageTest.cc Thu Jan 09 22:02:58 2020 +0100
2.3 @@ -622,6 +622,30 @@
2.4 }
2.5
2.6 // PASS
2.7 +TEST_F(KeyResetMessageTest, check_reset_grouped_own) {
2.8 + send_setup(); // lazy
2.9 + pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, alice_user_id.c_str(), NULL);
2.10 + PEP_STATUS status = myself(session, alice);
2.11 +
2.12 + ASSERT_EQ(status , PEP_STATUS_OK);
2.13 + ASSERT_TRUE(alice->fpr && alice->fpr[0]);
2.14 + ASSERT_TRUE(alice->me);
2.15 + ASSERT_STREQ(alice->fpr, alice_fpr);
2.16 +
2.17 + status = set_identity_flags(session, alice, alice->flags | PEP_idf_devicegroup);
2.18 + status = key_reset_identity(session, alice, alice_fpr);
2.19 + status = myself(session, alice);
2.20 + ASSERT_EQ(status , PEP_STATUS_OK);
2.21 + char* alice_new_fpr = alice->fpr;
2.22 + ASSERT_TRUE(alice_new_fpr && alice_new_fpr[0]);
2.23 + ASSERT_STRNE(alice_fpr, alice_new_fpr);
2.24 +
2.25 + ASSERT_EQ(m_queue.size(), 1);
2.26 +
2.27 +}
2.28 +
2.29 +
2.30 +// PASS
2.31 TEST_F(KeyResetMessageTest, check_reset_ident_other_pub_fpr) {
2.32 send_setup(); // lazy
2.33 pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, bob_user_id.c_str(), NULL);
3.1 --- a/test/src/KeyringImportTest.cc Thu Jan 09 09:19:36 2020 +0100
3.2 +++ b/test/src/KeyringImportTest.cc Thu Jan 09 22:02:58 2020 +0100
3.3 @@ -130,7 +130,7 @@
3.4 pEp_identity *id = new_identity(address, NULL, NULL, NULL);
3.5 PEP_STATUS status = update_identity(session, id);
3.6 ASSERT_EQ(status , PEP_STATUS_OK);
3.7 - output_stream << "Got: " << (id->fpr ?: "NULL") << " -> " << (id->address ?: "NULL") << endl;
3.8 + output_stream << "Got: " << (id->fpr ? id->fpr : "NULL") << " -> " << (id->address ? id->address : "NULL") << endl;
3.9
3.10 // We should always get the same fingerprint.
3.11 ASSERT_NE(id->fpr, nullptr);
3.12 @@ -197,7 +197,7 @@
3.13 pEp_identity *id = new_identity(address, NULL, NULL, NULL);
3.14 PEP_STATUS status = update_identity(session, id);
3.15 ASSERT_EQ(status , PEP_STATUS_OK);
3.16 - output_stream << "Got: " << (id->fpr ?: "NULL") << " (expected: " << fpr << ") -> " << (id->address ?: "NULL") << endl;
3.17 + output_stream << "Got: " << (id->fpr ? id->fpr : "NULL") << " (expected: " << fpr << ") -> " << (id->address ? id->address : "NULL") << endl;
3.18
3.19 // We should always get the same fingerprint.
3.20 ASSERT_NE(id->fpr, nullptr);