From 46b0697aa2cea6d28799ba78bf31f9574f48de39 Mon Sep 17 00:00:00 2001 From: Krista 'DarthMama' Bennett Date: Tue, 7 Jan 2020 22:35:39 +0100 Subject: [PATCH] A metric buttload of code that I finally need to stop shelving and unshelving - new key reset, with bugs. --- src/key_reset.c | 613 ++++++++++++++++++++++++-------- src/key_reset.h | 18 +- src/message.h | 1 - src/message_api.c | 156 ++++++-- src/pEpEngine.c | 178 +++++++++- src/pEpEngine.h | 2 + src/pEp_internal.h | 1 + test/src/KeyResetMessageTest.cc | 14 +- 8 files changed, 776 insertions(+), 207 deletions(-) diff --git a/src/key_reset.c b/src/key_reset.c index 8d31a433..d6a2eacb 100644 --- a/src/key_reset.c +++ b/src/key_reset.c @@ -7,7 +7,10 @@ #include "key_reset.h" #include "distribution_codec.h" #include "map_asn1.h" +#include "keymanagement.h" +#include "baseprotocol.h" #include "../asn.1/Distribution.h" +#include "Sync_impl.h" // this seems... bad #include #include @@ -17,8 +20,90 @@ #define KEY_RESET_MAJOR_VERSION 1L #define KEY_RESET_MINOR_VERSION 0L +static PEP_STATUS _generate_keyreset_command_message(PEP_SESSION session, + const pEp_identity* from_ident, + const pEp_identity* to_ident, + const char* old_fpr, + const char* new_fpr, + bool is_private, + message** dst) { + + if (!session || !from_ident || !old_fpr || !new_fpr || !dst) + return PEP_ILLEGAL_VALUE; + + // safe cast + if (!is_me(session, (pEp_identity*)from_ident)) + return PEP_ILLEGAL_VALUE; + + PEP_STATUS status = PEP_STATUS_OK; + + *dst = NULL; + + stringlist_t* keydata = NULL; + + // Ok, generate payload here... + pEp_identity* outgoing_ident = identity_dup(from_ident); + if (!outgoing_ident) + return PEP_OUT_OF_MEMORY; + free(outgoing_ident->fpr); + outgoing_ident->fpr = strdup(old_fpr); + if (!outgoing_ident->fpr) + return PEP_OUT_OF_MEMORY; + + // Need payload now + keyreset_command* kr_command = new_keyreset_command(outgoing_ident, new_fpr); + keyreset_command_list* kr_list = new_keyreset_command_list(kr_command); + char* payload = NULL; + size_t size = 0; + status = key_reset_commands_to_PER(kr_list, &payload, &size); + message* msg = NULL; + status = base_prepare_message(session, outgoing_ident, to_ident, + BASE_KEYRESET, payload, size, NULL, + &msg); + if (status) { + free(msg); + return status; + } + if (!msg) + return PEP_OUT_OF_MEMORY; + if (!msg->attachments) + return PEP_UNKNOWN_ERROR; + + char* key_material = NULL; + size_t datasize = 0; + status = export_key(session, new_fpr, &key_material, &datasize); + + if (datasize > 0 && key_material) { + if (status) { + free_stringlist(keydata); + return status; + } + stringlist_add(keydata, key_material); + + key_material = NULL; + datasize = 0; + if (is_private) { + status = export_secret_key(session, new_fpr, &key_material, &datasize); + if (status) { + free_stringlist(keydata); + return status; + } + if (datasize > 0 && key_material) + stringlist_add(keydata, key_material); + } + } + // Attach to message + stringlist_t* curr_key = keydata; + for ( ; curr_key && curr_key->value; curr_key = curr_key->next) { + bloblist_add(msg->attachments, curr_key->value, size, "application/pgp-keys", + "file://pEpkey.asc"); + } + return status; +} + PEP_STATUS has_key_reset_been_sent( PEP_SESSION session, + const char* from_addr, const char* user_id, const char* revoked_fpr, bool* contacted) @@ -29,7 +114,7 @@ PEP_STATUS has_key_reset_been_sent( assert(revoked_fpr); assert(!EMPTYSTR(user_id)); - if (!session || !contacted || EMPTYSTR(revoked_fpr) || EMPTYSTR(user_id)) + if (!session || !contacted || EMPTYSTR(from_addr) || EMPTYSTR(revoked_fpr) || EMPTYSTR(user_id)) return PEP_ILLEGAL_VALUE; *contacted = false; @@ -46,7 +131,9 @@ PEP_STATUS has_key_reset_been_sent( sqlite3_reset(session->was_id_for_revoke_contacted); sqlite3_bind_text(session->was_id_for_revoke_contacted, 1, revoked_fpr, -1, SQLITE_STATIC); - sqlite3_bind_text(session->was_id_for_revoke_contacted, 2, user_id, -1, + sqlite3_bind_text(session->was_id_for_revoke_contacted, 2, from_addr, -1, + SQLITE_STATIC); + sqlite3_bind_text(session->was_id_for_revoke_contacted, 3, user_id, -1, SQLITE_STATIC); int result = sqlite3_step(session->was_id_for_revoke_contacted); switch (result) { @@ -64,26 +151,26 @@ PEP_STATUS has_key_reset_been_sent( return PEP_STATUS_OK; } -//static const char *sql_set_revoke_contact_as_notified = -// "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;"; - PEP_STATUS set_reset_contact_notified( PEP_SESSION session, + const char* own_address, const char* revoke_fpr, const char* contact_id ) { PEP_STATUS status = PEP_STATUS_OK; - assert(session && !EMPTYSTR(revoke_fpr) && !EMPTYSTR(contact_id)); + assert(session && !EMPTYSTR(own_address) && !EMPTYSTR(revoke_fpr) && !EMPTYSTR(contact_id)); - if (!session || EMPTYSTR(revoke_fpr) || EMPTYSTR(contact_id)) + if (!session || EMPTYSTR(own_address) || EMPTYSTR(revoke_fpr) || EMPTYSTR(contact_id)) return PEP_ILLEGAL_VALUE; sqlite3_reset(session->set_revoke_contact_as_notified); sqlite3_bind_text(session->set_revoke_contact_as_notified, 1, revoke_fpr, -1, SQLITE_STATIC); - sqlite3_bind_text(session->set_revoke_contact_as_notified, 2, contact_id, -1, + sqlite3_bind_text(session->set_revoke_contact_as_notified, 2, own_address, -1, + SQLITE_STATIC); + sqlite3_bind_text(session->set_revoke_contact_as_notified, 3, contact_id, -1, SQLITE_STATIC); int result; @@ -102,149 +189,266 @@ PEP_STATUS set_reset_contact_notified( return status; } - +// FIXME: fpr ownership PEP_STATUS receive_key_reset(PEP_SESSION session, message* reset_msg) { - if (!session || !reset_msg) + if (!session || !reset_msg || !reset_msg->_sender_fpr) return PEP_ILLEGAL_VALUE; - pEp_identity* sender_id = reset_msg->from; - - if (!sender_id) - return PEP_MALFORMED_KEY_RESET_MSG; - - PEP_STATUS status = update_identity(session, sender_id); - if (!sender_id->user_id) - return PEP_UNKNOWN_ERROR; - - if (is_me(session, sender_id)) - return PEP_ILLEGAL_VALUE; - - if (!reset_msg->longmsg || strncmp(reset_msg->longmsg, "OLD: ", 5) != 0) - return PEP_MALFORMED_KEY_RESET_MSG; + PEP_STATUS status = PEP_STATUS_OK; - status = PEP_STATUS_OK; - char* old_fpr = NULL; - char* new_fpr = NULL; - stringlist_t* keylist = NULL; - pEp_identity* temp_ident = identity_dup(sender_id); - if (!temp_ident) { - status = PEP_OUT_OF_MEMORY; - goto pEp_free; - } - - char* rest = NULL; - char* p = strtok_r(reset_msg->longmsg, "\r\n", &rest); - if (!EMPTYSTR(p + 5)) - old_fpr = strdup(p + 5); + + char* sender_fpr = reset_msg->_sender_fpr; + + bool revoked = false; + + status = key_revoked(session, sender_fpr, &revoked); + + if (status != PEP_STATUS_OK) + return status; + + // Bail if revoked + if (revoked) { + return PEP_ILLEGAL_VALUE; // could be an attack + } + // Otherwise, bail else { - status = PEP_MALFORMED_KEY_RESET_MSG; - goto pEp_free; + bool mistrusted = false; + status = is_mistrusted_key(session, sender_fpr, &mistrusted); + + if (status != PEP_STATUS_OK) + return status; + + if (mistrusted) + return PEP_ILLEGAL_VALUE; } + - bool own_key = false; - status = is_own_key(session, old_fpr, &own_key); + // Parse reset message - if (own_key) { - // Nope, no one can make us our own default. If we want to do that, - // that's keysync, NOT key reset. - status = PEP_ILLEGAL_VALUE; - goto pEp_free; + pEp_identity* sender_id = reset_msg->from; + + if (!sender_id) + return PEP_MALFORMED_KEY_RESET_MSG; + + if (is_me(session, sender_id)) { + // first off, we need to make sure we're up-to-date + status = myself(session, sender_id); } + else { + status = update_identity(session, sender_id); + if (!sender_id->user_id) + return PEP_UNKNOWN_ERROR; + } + + bool sender_own_key = false; + + if (is_me(session, sender_id)) { + // Do own-reset-checks + status = is_own_key(session, sender_fpr, &sender_own_key); + + if (status != PEP_STATUS_OK) + return status; + + // Should we mistrust the sender_fpr here?? + if (!sender_own_key) + return PEP_ILLEGAL_VALUE; // actually, this is an attack + + // Make sure it's a TRUSTED own key + char* keyholder = sender_id->fpr; + + sender_id->fpr = sender_fpr; + status = get_trust(session, sender_id); + sender_id->fpr = keyholder; - p = strtok_r(NULL, "\r\n", &rest); - if (strncmp(p, "NEW: ", 5) != 0 || EMPTYSTR(p + 5)) { - status = PEP_MALFORMED_KEY_RESET_MSG; - goto pEp_free; + if (sender_id->comm_type < PEP_ct_pEp) + return PEP_ILLEGAL_VALUE; } - - new_fpr = strdup(p + 5); - // Reset the original key - status = key_reset(session, old_fpr, temp_ident, NULL, NULL); + status = PEP_STATUS_OK; + char* old_fpr = NULL; + char* new_fpr = NULL; + + size_t size = 0; + const char* payload = NULL; + + status = base_extract_message(session, + reset_msg, + BASE_KEYRESET, + &size, + &payload, + NULL); + if (status != PEP_STATUS_OK) - goto pEp_free; + return status; - status = find_keys(session, new_fpr, &keylist); + if (!payload || size == 0) + return PEP_MALFORMED_KEY_RESET_MSG; + + keyreset_command_list* resets = NULL; + + status = PER_to_key_reset_commands(payload, size, &resets); + if (status != PEP_STATUS_OK) - goto pEp_free; + return status; - if (!keylist) { - status = PEP_KEY_NOT_FOUND; - goto pEp_free; - } + if (!resets) + return PEP_MALFORMED_KEY_RESET_MSG; - // alright, we've checked as best we can. Let's set that baby. - sender_id->fpr = new_fpr; + keyreset_command_list* curr_cl = resets; - // This only sets as the default, does NOT TRUST IN ANY WAY - sender_id->comm_type = sender_id->comm_type & (~PEP_ct_confirmed); - status = set_identity(session, sender_id); + for ( ; curr_cl && curr_cl->command; curr_cl = curr_cl->next) { + keyreset_command* curr_cmd = curr_cl->command; + if (!curr_cmd || !curr_cmd->ident || !curr_cmd->ident->fpr || + !curr_cmd->ident->address) { + return PEP_MALFORMED_KEY_RESET_MSG; + } + // Make sure that this key is at least one we associate + // with the sender. FIXME: check key election interaction + // N.B. If we ever allow ourselves to send resets to ourselves + // for not-own stuff, this will have to be revised + pEp_identity* curr_ident = curr_cmd->ident; + + old_fpr = curr_ident->fpr; + new_fpr = curr_cmd->new_key; + + status = find_keys(session, new_fpr, &keylist); + if (status != PEP_STATUS_OK) + goto pEp_free; + if (!keylist) { + status = PEP_MALFORMED_KEY_RESET_MSG; + goto pEp_free; + } + + // We need to update the identity to get the user_id + curr_ident->fpr = NULL; // ensure old_fpr is preserved + status = update_identity(session, curr_ident); + + // temp fpr set for function call + curr_ident->fpr = (char*)sender_fpr; + status = get_trust(session, curr_ident); + + PEP_comm_type ct_result = curr_ident->comm_type; + + // Reset fpr on ident struct in case we bail to fulfill ownership contract + curr_ident->fpr = old_fpr; + + if (status != PEP_STATUS_OK) + return status; + + // Basically, see if fpr is even in the database + // for this user - we'll get PEP_ct_unknown if it isn't + if (ct_result < PEP_ct_strong_but_unconfirmed) + return PEP_KEY_NOT_RESET; + + // Now check the fpr we're trying to change (old_fpr), which we reset a few lines above - + // again, if it doesn't belong to the user, we won't use it. + status = get_trust(session, curr_ident); + + if (status != PEP_STATUS_OK) + return status; + + if (curr_ident->comm_type < PEP_ct_strong_but_unconfirmed) + return PEP_KEY_NOT_RESET; + + // Hooray! We apparently now are dealing with keys + // belonging to the user from a message signed by + // the user. + if (!sender_own_key) { + status = key_reset(session, old_fpr, curr_ident); + if (status != PEP_STATUS_OK) + return status; + + // Make new key the default + curr_ident->fpr = new_fpr; - sender_id->fpr = NULL; // ownership for free + // This only sets as the default, does NOT TRUST IN ANY WAY + curr_ident->comm_type = curr_ident->comm_type & (~PEP_ct_confirmed); + status = set_identity(session, curr_ident); + if (status != PEP_STATUS_OK) + goto pEp_free; + } + else { + // set new key as the default for this identity + // N.B. If for some reason this is only a pubkey, + // then so be it - but we need to double-check to + // ensure that in this case, we end up with a private one, + // so talk to vb about this. + // Make new key the default + curr_ident->fpr = new_fpr; + status = set_own_key(session, curr_ident, new_fpr); + + if (status != PEP_STATUS_OK) + return status; + + // key reset on old key + status = key_reset(session, old_fpr, curr_ident); + if (status != PEP_STATUS_OK) + return status; + } + old_fpr = NULL; + new_fpr = NULL; + } + pEp_free: free_stringlist(keylist); free(old_fpr); free(new_fpr); - free_identity(temp_ident); return status; } PEP_STATUS create_standalone_key_reset_message(PEP_SESSION session, message** dst, + pEp_identity* own_identity, pEp_identity* recip, const char* old_fpr, const char* new_fpr) { - if (!dst || !recip->user_id || !recip->address) + if (!dst || !own_identity || EMPTYSTR(own_identity->address) + || !recip || EMPTYSTR(recip->user_id) + || EMPTYSTR(recip->address)) return PEP_ILLEGAL_VALUE; - if (!old_fpr || !new_fpr) + if (EMPTYSTR(old_fpr) || EMPTYSTR(new_fpr)) return PEP_ILLEGAL_VALUE; *dst = NULL; - // Get own identity user has corresponded with - pEp_identity* own_identity = NULL; - PEP_STATUS status = get_own_ident_for_contact_id(session, - recip, - &own_identity); + message* reset_msg = NULL; + + PEP_STATUS status = _generate_keyreset_command_message(session, own_identity, + recip, + old_fpr, new_fpr, false, + &reset_msg); + if (status != PEP_STATUS_OK) - return status; - - message* reset_message = new_message(PEP_dir_outgoing); - reset_message->from = own_identity; - reset_message->to = new_identity_list(identity_dup(recip)); // ? - - const char* oldtag = "OLD: "; - const char* newtag = "\nNEW: "; - const size_t taglens = 11; - size_t full_len = taglens + strlen(old_fpr) + strlen(new_fpr) + 2; // \n and \0 - char* longmsg = calloc(full_len, 1); - strlcpy(longmsg, oldtag, full_len); - strlcat(longmsg, old_fpr, full_len); - strlcat(longmsg, newtag, full_len); - strlcat(longmsg, new_fpr, full_len); - strlcat(longmsg, "\n", full_len); - reset_message->longmsg = longmsg; - reset_message->shortmsg = strdup("Key reset"); + goto pEp_free; + + if (!reset_msg) + return PEP_ILLEGAL_VALUE; + + if (!reset_msg->attachments) + return PEP_UNKNOWN_ERROR; message* output_msg = NULL; - status = encrypt_message(session, reset_message, NULL, + status = encrypt_message(session, reset_msg, NULL, &output_msg, PEP_enc_PGP_MIME, PEP_encrypt_flag_key_reset_only); if (status == PEP_STATUS_OK) *dst = output_msg; - free_message(reset_message); +pEp_free: + + free_message(reset_msg); return status; } PEP_STATUS send_key_reset_to_recents(PEP_SESSION session, + pEp_identity* from_ident, const char* old_fpr, const char* new_fpr) { assert(old_fpr); @@ -287,18 +491,27 @@ PEP_STATUS send_key_reset_to_recents(PEP_SESSION session, // Check if they've already been told - this shouldn't be the case, but... bool contacted = false; - status = has_key_reset_been_sent(session, user_id, old_fpr, &contacted); + status = has_key_reset_been_sent(session, from_ident->address, user_id, old_fpr, &contacted); if (status != PEP_STATUS_OK) goto pEp_free; if (contacted) continue; + // Make sure they've ever *contacted* this address + bool in_contact_w_this_address = false; + status = has_partner_contacted_address(session, from_ident->address, curr_id->user_id, + &in_contact_w_this_address); + + if (!in_contact_w_this_address) + continue; + // if not, make em a message reset_msg = NULL; status = create_standalone_key_reset_message(session, &reset_msg, + from_ident, curr_id, old_fpr, new_fpr); @@ -322,7 +535,7 @@ PEP_STATUS send_key_reset_to_recents(PEP_SESSION session, } // Put into notified DB - status = set_reset_contact_notified(session, old_fpr, user_id); + status = set_reset_contact_notified(session, from_ident->address, old_fpr, user_id); if (status != PEP_STATUS_OK) goto pEp_free; } @@ -341,7 +554,7 @@ DYNAMIC_API PEP_STATUS key_reset_identity( if (!session || !ident || (ident && (EMPTYSTR(ident->user_id) || EMPTYSTR(ident->address)))) return PEP_ILLEGAL_VALUE; - return key_reset(session, fpr, ident, NULL, NULL); + return key_reset(session, fpr, ident); } DYNAMIC_API PEP_STATUS key_reset_user( @@ -360,13 +573,121 @@ DYNAMIC_API PEP_STATUS key_reset_user( if (is_me(session, input_ident) && EMPTYSTR(fpr)) return PEP_ILLEGAL_VALUE; - PEP_STATUS status = key_reset(session, fpr, input_ident, NULL, NULL); + PEP_STATUS status = key_reset(session, fpr, input_ident); free_identity(input_ident); return status; } DYNAMIC_API PEP_STATUS key_reset_all_own_keys(PEP_SESSION session) { - return key_reset(session, NULL, NULL, NULL, NULL); + return key_reset(session, NULL, NULL); +} + + +static PEP_STATUS _key_reset_device_group_for_shared_key(PEP_SESSION session, + identity_list* key_idents, + const char* old_key) { + assert(session); + assert(key_idents); + assert(old_key); + + if (!session || !key_idents || EMPTYSTR(old_key)) + return PEP_ILLEGAL_VALUE; + + messageToSend_t send_cb = session->messageToSend; + if (!send_cb) + return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK; + + PEP_STATUS status = PEP_STATUS_OK; + + // each of these has the same key and needs a new one. + identity_list* curr_ident; + for (curr_ident = key_idents; curr_ident && curr_ident->ident; curr_ident = curr_ident->next) { + if (curr_ident->ident->flags & PEP_idf_devicegroup) { + pEp_identity* ident = curr_ident->ident; + free(ident->fpr); + ident->fpr = NULL; + status = generate_keypair(session, ident); + if (status != PEP_STATUS_OK) + return status; + + } + else { + status = key_reset(session, old_key, curr_ident->ident); + } + } + + // Ok, everyone's got a new keypair. Hoorah! + // generate, sign, and push messages into queue + for (curr_ident = key_idents; curr_ident && curr_ident->ident; curr_ident = curr_ident->next) { + if (curr_ident->ident->flags & PEP_idf_devicegroup) { + message* outmsg = NULL; + + // FIXME - do we have to? Maybe check IN the funct + pEp_identity* to_me = identity_dup(curr_ident->ident); + if (!to_me) + return PEP_OUT_OF_MEMORY; + + status = _generate_keyreset_command_message(session, curr_ident->ident, to_me, + old_key, curr_ident->ident->fpr, + true, &outmsg); + + message* enc_msg = NULL; + + // encrypt this baby and get out + // extra keys??? + status = encrypt_message(session, outmsg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0); + + if (status != PEP_STATUS_OK) { + goto pEp_free; + } + + // insert into queue + status = send_cb(enc_msg); + + if (status != PEP_STATUS_OK) { + free(enc_msg); + goto pEp_free; + } + // Does there need to be some kind of signal here for sync? + } + } + + // Ok, we've signed everything we need to with the old key, + // Revoke that baby. + status = revoke_key(session, old_key, NULL); + + if (!status) + goto pEp_free; + + for (curr_ident = key_idents; curr_ident && curr_ident->ident; curr_ident = curr_ident->next) { + if (curr_ident->ident->flags & PEP_idf_devicegroup) { + pEp_identity* ident = curr_ident->ident; + + // N.B. This sort of sucks because we overwrite this every time. + // But this case is infrequent and we don't rely on the binding. + if (status == PEP_STATUS_OK) + status = set_revoked(session, old_key, curr_ident->ident->fpr, time(NULL)); + + if (!status) + goto pEp_free; + + pEp_identity* tmp_ident = identity_dup(ident); + if (!tmp_ident) { + status = PEP_OUT_OF_MEMORY; + goto pEp_free; + } + free(tmp_ident->fpr); + + // for all active communication partners: + // active_send revocation + tmp_ident->fpr = strdup(old_key); // freed in free_identity + if (status == PEP_STATUS_OK) + status = send_key_reset_to_recents(session, tmp_ident, old_key, ident->fpr); + free_identity(tmp_ident); + } + } +pEp_free: + return status; } // Notes to integrate into header: @@ -374,9 +695,7 @@ DYNAMIC_API PEP_STATUS key_reset_all_own_keys(PEP_SESSION session) { PEP_STATUS key_reset( PEP_SESSION session, const char* key_id, - pEp_identity* ident, - identity_list** own_identities, - stringlist_t** own_revoked_fprs + pEp_identity* ident ) { if (!session || (ident && EMPTYSTR(ident->user_id))) @@ -426,7 +745,7 @@ PEP_STATUS key_reset( for (curr_key = keys; curr_key && curr_key->value; curr_key = curr_key->next) { // FIXME: Is the ident really necessary? - status = key_reset(session, curr_key->value, tmp_ident, own_identities, own_revoked_fprs); + status = key_reset(session, curr_key->value, tmp_ident); if (status != PEP_STATUS_OK) break; } @@ -500,20 +819,21 @@ PEP_STATUS key_reset( if (status == PEP_STATUS_OK) { // now have ident list, or should identity_list* curr_ident; - - for (curr_ident = key_idents; curr_ident && curr_ident->ident; - curr_ident = curr_ident->next) { - - pEp_identity* this_identity = curr_ident->ident; - // Do the full reset on this identity - status = key_reset(session, fpr_copy, this_identity, own_identities, own_revoked_fprs); - - // Ident list gets freed below, do not free here! - if (status != PEP_STATUS_OK) - break; - + bool is_grouped = false; + if (!deviceGrouped(session, &is_grouped)) { + for (curr_ident = key_idents; curr_ident && curr_ident->ident; + curr_ident = curr_ident->next) { + + pEp_identity* this_identity = curr_ident->ident; + // Do the full reset on this identity + status = key_reset(session, fpr_copy, this_identity); + + // Ident list gets freed below, do not free here! + } } + else { + status = _key_reset_device_group_for_shared_key(session, key_idents, fpr_copy); } } // Ok, we've either now reset for each own identity with this key, or // we got an error and want to bail anyway. @@ -521,8 +841,14 @@ PEP_STATUS key_reset( } } - // Base case for is_own_private starts here + if (EMPTYSTR(tmp_ident->address)) { + return PEP_UNKNOWN_ERROR; // FIXME - what case IS this? + } + // Ok, first we generate a new key. + + // Base case for is_own_private starts here + // tmp ident is an actual identity now (not just a skeleton?) status = revoke_key(session, fpr_copy, NULL); // If we have a full identity, we have some cleanup and generation tasks here @@ -532,23 +858,9 @@ PEP_STATUS key_reset( tmp_ident->fpr = NULL; status = myself(session, tmp_ident); } - if (status == PEP_STATUS_OK && tmp_ident->fpr && strcmp(fpr_copy, tmp_ident->fpr) != 0) { + if (status == PEP_STATUS_OK && tmp_ident->fpr && strcmp(fpr_copy, tmp_ident->fpr) != 0) new_key = strdup(tmp_ident->fpr); -// status = set_own_key(session, tmp_ident, new_key); - } - - if (own_revoked_fprs) { - // We can dedup this later - if (!(*own_revoked_fprs)) - *own_revoked_fprs = new_stringlist(NULL); - - char* revkey = strdup(fpr_copy); - if (!revkey) { - status = PEP_OUT_OF_MEMORY; - goto pEp_free; - } - stringlist_add(*own_revoked_fprs, revkey); - } + // Error handling? // mistrust fpr from trust tmp_ident->fpr = fpr_copy; @@ -562,18 +874,6 @@ PEP_STATUS key_reset( // Update fpr for outgoing status = myself(session, tmp_ident); } - - if (status == PEP_STATUS_OK && own_identities) { - if (!(*own_identities)) - *own_identities = new_identity_list(NULL); - - pEp_identity* new_ident = identity_dup(tmp_ident); - if (!new_ident) { - status = PEP_OUT_OF_MEMORY; - goto pEp_free; - } - identity_list_add(*own_identities, new_ident); - } } if (status == PEP_STATUS_OK) @@ -594,8 +894,11 @@ PEP_STATUS key_reset( status = set_revoked(session, fpr_copy, new_key, time(NULL)); // for all active communication partners: // active_send revocation + + tmp_ident->fpr = fpr_copy; if (status == PEP_STATUS_OK) - status = send_key_reset_to_recents(session, fpr_copy, new_key); + status = send_key_reset_to_recents(session, tmp_ident, fpr_copy, new_key); + tmp_ident->fpr = NULL; } } // end is_own_private else { @@ -642,6 +945,7 @@ pEp_free: return status; } +/* static stringlist_t* collect_key_material(PEP_SESSION session, stringlist_t* fprs) { stringlist_t* keydata = NULL; stringlist_t* curr_fpr = fprs; @@ -702,6 +1006,17 @@ PEP_STATUS key_reset_own_and_deliver_revocations(PEP_SESSION session, } if (datasize > 0 && key_material) stringlist_add(keydata, key_material); + + key_material = NULL; + datasize = 0; + status = export_private_keys(session, curr_ident->ident->fpr, &key_material, &datasize); + if (status) { + free_stringlist(keydata); + return status; + } + if (datasize > 0 && key_material) + stringlist_add(keydata, key_material); + } curr_ident = curr_ident->next; } @@ -713,7 +1028,7 @@ PEP_STATUS key_reset_own_and_deliver_revocations(PEP_SESSION session, free(revoked_fprs); return PEP_STATUS_OK; } - +*/ Distribution_t *Distribution_from_keyreset_command_list( const keyreset_command_list *command_list, Distribution_t *dist @@ -778,6 +1093,7 @@ enomem: return NULL; } + PEP_STATUS key_reset_commands_to_PER(const keyreset_command_list *command_list, char **cmds, size_t *size) { PEP_STATUS status = PEP_STATUS_OK; @@ -908,4 +1224,3 @@ the_end: ASN_STRUCT_FREE(asn_DEF_Distribution, dist); return status; } - diff --git a/src/key_reset.h b/src/key_reset.h index 9bfd130b..54085427 100644 --- a/src/key_reset.h +++ b/src/key_reset.h @@ -114,11 +114,6 @@ DYNAMIC_API PEP_STATUS key_reset_all_own_keys(PEP_SESSION session); // if NULL and fpr is non-NULL, we'll reset the key for all // associated identities. If both ident and fpr are NULL, see // the fpr arg documentation. -// own_identities (out) IF this is resetting own identities, passing in a pointer here -// will cause key_reset to return a list of own_identities featuring -// the new keys -// own_revoked_fprs (out) IF this is resetting own identities, passing in a pointer here -// will cause key_reset to send a list of the revoked fprs // // Note: ident->fpr is always ignored // @@ -128,26 +123,26 @@ DYNAMIC_API PEP_STATUS key_reset_all_own_keys(PEP_SESSION session); PEP_STATUS key_reset( PEP_SESSION session, const char* fpr, - pEp_identity* ident, - identity_list** own_identities, - stringlist_t** own_revoked_fprs + pEp_identity* ident ); - +/* PEP_STATUS key_reset_own_and_deliver_revocations(PEP_SESSION session, identity_list** own_identities, stringlist_t** revocations, stringlist_t** keys); - +*/ PEP_STATUS has_key_reset_been_sent( PEP_SESSION session, + const char* from_addr, const char* user_id, const char* revoked_fpr, bool* contacted); PEP_STATUS set_reset_contact_notified( PEP_SESSION session, + const char* own_address, const char* revoke_fpr, const char* contact_id ); @@ -157,11 +152,14 @@ PEP_STATUS receive_key_reset(PEP_SESSION session, PEP_STATUS create_standalone_key_reset_message(PEP_SESSION session, message** dst, + pEp_identity* own_identity, pEp_identity* recip, const char* old_fpr, const char* new_fpr); + PEP_STATUS send_key_reset_to_recents(PEP_SESSION session, + pEp_identity* from_ident, const char* old_fpr, const char* new_fpr); diff --git a/src/message.h b/src/message.h index 38b85b5e..dc577397 100644 --- a/src/message.h +++ b/src/message.h @@ -80,7 +80,6 @@ typedef struct _message_ref_list { struct _message_ref_list *next; } message_ref_list; - // new_message() - allocate new message // // parameters: diff --git a/src/message_api.c b/src/message_api.c index 8532c2a9..6a94ebc2 100644 --- a/src/message_api.c +++ b/src/message_api.c @@ -3395,6 +3395,65 @@ static bool _have_extrakeys(stringlist_t *keylist) && keylist->value[0]; } +// practically speaking, only useful to get user_id/address intersection +// we presume no dups in the first list if you're looking for +// a unique result. +static PEP_STATUS ident_list_intersect(identity_list* list_a, + identity_list* list_b, + identity_list** intersection) { + + if (!intersection) + return PEP_ILLEGAL_VALUE; + + *intersection = NULL; + if (!list_a || !list_b || !list_a->ident || !list_b->ident) + return PEP_STATUS_OK; + + + *intersection = NULL; + + identity_list* isect = NULL; + + identity_list* curr_a = list_a; + for ( ; curr_a && curr_a->ident; curr_a = curr_a->next) { + pEp_identity* id_a = curr_a->ident; + if (EMPTYSTR(id_a->user_id) || EMPTYSTR(id_a->address)) + continue; + + identity_list* curr_b = list_b; + for ( ; curr_b && curr_b->ident; curr_b = curr_b->next) { + pEp_identity* id_b = curr_b->ident; + if (EMPTYSTR(id_b->user_id) || EMPTYSTR(id_b->address)) + continue; + + if (strcmp(id_a->user_id, id_b->user_id) == 0 && + strcmp(id_a->address, id_b->address) == 0) { + pEp_identity* result_id = identity_dup(id_b); + if (!id_b) + goto enomem; + + if (!isect) { + isect = new_identity_list(result_id); + if (!isect) + goto enomem; + } + else { + if (!identity_list_add(isect, result_id)) + goto enomem; + } + break; + } + } + } + *intersection = isect; + return PEP_STATUS_OK; + +enomem: + free_identity_list(isect); + return PEP_OUT_OF_MEMORY; + +} + static PEP_STATUS _decrypt_message( PEP_SESSION session, message *src, @@ -3924,42 +3983,73 @@ static PEP_STATUS _decrypt_message( continue; // Again, shouldn't occur if (curr_pair->key && curr_pair->value) { - status = create_standalone_key_reset_message(session, - &reset_msg, - msg->from, - curr_pair->key, - curr_pair->value); - - // If we can't find the identity, this is someone we've never mailed, so we just - // go on letting them use the wrong key until we mail them ourselves. (Spammers, etc) - if (status != PEP_CANNOT_FIND_IDENTITY) { + /* Figure out which address(es) this came to so we know who to reply from */ + + identity_list* my_rev_ids = NULL; + + /* check by replacement ID for identities which used this key? */ + status = get_identities_by_main_key_id(session, curr_pair->value, + &my_rev_ids); + + if (status == PEP_STATUS_OK && my_rev_ids) { + // get identities in this list the message was to/cc'd to (not for bcc) + identity_list* used_ids_for_key = NULL; + status = ident_list_intersect(my_rev_ids, msg->to, &used_ids_for_key); if (status != PEP_STATUS_OK) - goto pEp_error; + goto pEp_error; // out of memory - if (!reset_msg) { - status = PEP_OUT_OF_MEMORY; - goto pEp_error; - } - // insert into queue - if (session->messageToSend) - status = session->messageToSend(reset_msg); - else - status = PEP_SYNC_NO_MESSAGE_SEND_CALLBACK; - - - if (status == PEP_STATUS_OK) { - // Put into notified DB - status = set_reset_contact_notified(session, curr_pair->key, msg->from->user_id); - if (status != PEP_STATUS_OK) // It's ok to barf because it's a DB problem?? - goto pEp_error; - } - else { - // According to Volker, this would only be a fatal error, so... - free_message(reset_msg); // ?? - reset_msg = NULL; // ?? + identity_list* used_cc_ids = NULL; + status = ident_list_intersect(my_rev_ids, msg->to, &used_cc_ids); + if (status != PEP_STATUS_OK) goto pEp_error; - } - } + + used_ids_for_key = identity_list_join(used_ids_for_key, used_cc_ids); + + identity_list* curr_recip = used_ids_for_key; + + for ( ; curr_recip && curr_recip->ident; curr_recip = curr_recip->next) { + if (!is_me(session, curr_recip->ident)) + continue; + + status = create_standalone_key_reset_message(session, + &reset_msg, + curr_recip->ident, + msg->from, + curr_pair->key, + curr_pair->value); + + // If we can't find the identity, this is someone we've never mailed, so we just + // go on letting them use the wrong key until we mail them ourselves. (Spammers, etc) + if (status != PEP_CANNOT_FIND_IDENTITY) { + if (status != PEP_STATUS_OK) + goto pEp_error; + + if (!reset_msg) { + status = PEP_OUT_OF_MEMORY; + goto pEp_error; + } + // insert into queue + if (session->messageToSend) + status = session->messageToSend(reset_msg); + else + status = PEP_SYNC_NO_MESSAGE_SEND_CALLBACK; + + + if (status == PEP_STATUS_OK) { + // Put into notified DB + status = set_reset_contact_notified(session, curr_recip->ident->address, curr_pair->key, msg->from->user_id); + if (status != PEP_STATUS_OK) // It's ok to barf because it's a DB problem?? + goto pEp_error; + } + else { + // According to Volker, this would only be a fatal error, so... + free_message(reset_msg); // ?? + reset_msg = NULL; // ?? + goto pEp_error; + } + } + } + } // else we couldn't find an ident for replacement key } } } diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 44f91e73..ec52f941 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -503,19 +503,22 @@ static const char *sql_get_own_address_binding_from_contact = "select own_address from social_graph where own_userid = ?1 and contact_userid = ?2 ;"; static const char *sql_set_revoke_contact_as_notified = - "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;"; + "insert or replace into revocation_contact_list(fpr, own_address, contact_id) values (?1, ?2, ?3) ;"; static const char *sql_get_contacted_ids_from_revoke_fpr = "select * from revocation_contact_list where fpr = ?1 ;"; static const char *sql_was_id_for_revoke_contacted = - "select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;"; + "select count(*) from revocation_contact_list where fpr = ?1 and own_address = ?2 and contact_id = ?3 ;"; + +static const char *sql_has_id_contacted_address = + "select count(*) from social_graph where own_address = ?1 and contact_userid = ?2 ;"; // We only need user_id and address, since in the main usage, we'll call update_identity // on this anyway when sending out messages. static const char *sql_get_last_contacted = "select user_id, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; "; - + static int user_version(void *_version, int count, char **text, char **name) { assert(_version); @@ -806,6 +809,112 @@ void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){ fprintf(stderr, "(%d) %s\n", iErrCode, zMsg); } +static PEP_STATUS upgrade_revoc_contact_to_13(PEP_SESSION session) { + // I HATE SQLITE. + PEP_STATUS status = PEP_STATUS_OK; + int int_result = 0; + + // Ok, first we ADD the column so we can USE it. + // We will end up propagating the "error" this first time + // (one-to-one revoke-replace relationships), but since key reset + // hasn't been used in production, this is not a customer-facing + // issue. + int_result = sqlite3_exec( + session->db, + "alter table revocation_contact_list\n" + " add column own_address text\n", + NULL, + NULL, + NULL + ); + assert(int_result == SQLITE_OK); + + sqlite3_stmt* update_revoked_w_addr_stmt = NULL; + const char* sql_query = "update revocation_contact_list set own_address = ?1 where fpr = ?2;"; + sqlite3_prepare_v2(session->db, sql_query, -1, &update_revoked_w_addr_stmt, NULL); + + // the best we can do here is search per address, since these + // are no longer associated with an identity. For now, if we find + // something we can't add an address to, we'll delete the record. + // this should not, in the current environment, ever happen, but + // since we need to make the address part of the primary key, it's + // the right thing to do. sqlite does support null fields in a primary + // key for a weird version compatibility reason, but that doesn't + // mean we should use it, and we should be *safe*, not relying + // on an implementation-specific quirk which might be sanely removed + // in a future sqlite version. + stringpair_t* revoked_key_to_own_address = NULL; + + identity_list* id_list = NULL; + status = own_identities_retrieve(session, &id_list); + + if (!status || !id_list) + return PEP_STATUS_OK; // it's empty AFAIK (FIXME) + + identity_list* curr_own = id_list; + + // Ok, go through and find any keys associated with this address + for ( ; curr_own && curr_own->ident; curr_own = curr_own->next) { + if (EMPTYSTR(curr_own->ident->address)) // shouldn't happen + continue; + stringlist_t* keylist = NULL; + status = find_keys(session, curr_own->ident->address, &keylist); + stringlist_t* curr_key = keylist; + for ( ; curr_key && curr_key->value; curr_key = curr_key->next) { + if (EMPTYSTR(curr_key->value)) + continue; + + // We just do this lazily - if this isn't a revoked key, it + // won't do anything. + sqlite3_bind_text(update_revoked_w_addr_stmt, 1, curr_own->ident->address, -1, + SQLITE_STATIC); + sqlite3_bind_text(update_revoked_w_addr_stmt, 2, curr_key->value, -1, + SQLITE_STATIC); + + int_result = sqlite3_step(update_revoked_w_addr_stmt); + assert(int_result == SQLITE_DONE); + sqlite3_reset(update_revoked_w_addr_stmt); + } + } + sqlite3_finalize(update_revoked_w_addr_stmt); + + int_result = sqlite3_exec( + session->db, + "delete from revocation_contact_list where own_address is NULL;\n" + "PRAGMA foreign_keys=off;\n" + "BEGIN TRANSACTION;\n" + "create table if not exists _revocation_contact_list_new (\n" + " fpr text not null references pgp_keypair (fpr)\n" + " on delete cascade,\n" + " own_address text,\n" + " contact_id text not null references person (id)\n" + " on delete cascade on update cascade,\n" + " timestamp integer default (datetime('now')),\n" + " PRIMARY KEY(fpr, own_address, contact_id)\n" + ");\n" + "INSERT INTO _revocation_contact_list_new (fpr, " + " own_address, " + " contact_id) " + " SELECT revocation_contact_list.fpr, " + " revocation_contact_list.own_address, " + " revocation_contact_list.contact_id " + " FROM revocation_contact_list " + " WHERE 1;\n" + "DROP TABLE revocation_contact_list;\n" + "ALTER TABLE _revocation_contact_list_new RENAME TO revocation_contact_list;\n" + "COMMIT;\n" + "\n" + "PRAGMA foreign_keys=on;\n" + , + NULL, + NULL, + NULL + ); + assert(int_result == SQLITE_OK); + + return status; +} + #ifdef USE_GPG PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session); #endif // USE_GPG @@ -934,7 +1043,7 @@ DYNAMIC_API PEP_STATUS init( sqlite3_busy_timeout(_session->system_db, 1000); // increment this when patching DDL -#define _DDL_USER_VERSION "12" +#define _DDL_USER_VERSION "13" if (in_first) { @@ -1052,10 +1161,11 @@ DYNAMIC_API PEP_STATUS init( "create table if not exists revocation_contact_list (\n" " fpr text not null references pgp_keypair (fpr)\n" " on delete cascade,\n" + " own_address text,\n" " contact_id text not null references person (id)\n" " on delete cascade on update cascade,\n" " timestamp integer default (datetime('now')),\n" - " PRIMARY KEY(fpr, contact_id)\n" + " PRIMARY KEY(fpr, own_address, contact_id)\n" ");\n" , NULL, @@ -1103,7 +1213,10 @@ DYNAMIC_API PEP_STATUS init( // Sometimes the user_version wasn't set correctly. if (version == 1) { bool version_changed = true; - if (table_contains_column(_session, "identity", "pEp_version_major")) { + if (table_contains_column(_session, "revocation_contact_list", "own_address")) { + version = 13; + } + else if (table_contains_column(_session, "identity", "pEp_version_major")) { version = 12; } else if (db_contains_table(_session, "social_graph") > 0) { @@ -1555,6 +1668,12 @@ DYNAMIC_API PEP_STATUS init( if (status != PEP_STATUS_OK) return status; } + if (version < 13) { + status = upgrade_revoc_contact_to_13(_session); + assert(status == PEP_STATUS_OK); + if (status != PEP_STATUS_OK) + return status; + } } else { // Version from DB was 0, it means this is initial setup. @@ -1714,6 +1833,12 @@ DYNAMIC_API PEP_STATUS init( &_session->was_id_for_revoke_contacted, NULL); assert(int_result == SQLITE_OK); + int_result = sqlite3_prepare_v2(_session->db, + sql_has_id_contacted_address, + (int)strlen(sql_has_id_contacted_address), + &_session->has_id_contacted_address, NULL); + assert(int_result == SQLITE_OK); + int_result = sqlite3_prepare_v2(_session->db, sql_get_last_contacted, (int)strlen(sql_get_last_contacted), @@ -2022,7 +2147,9 @@ DYNAMIC_API void release(PEP_SESSION session) if (session->get_contacted_ids_from_revoke_fpr) sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr); if (session->was_id_for_revoke_contacted) - sqlite3_finalize(session->was_id_for_revoke_contacted); + sqlite3_finalize(session->was_id_for_revoke_contacted); + if (session->has_id_contacted_address) + sqlite3_finalize(session->has_id_contacted_address); if (session->get_last_contacted) sqlite3_finalize(session->get_last_contacted); if (session->set_pgp_keypair) @@ -3567,6 +3694,43 @@ PEP_STATUS bind_own_ident_with_contact_ident(PEP_SESSION session, return PEP_STATUS_OK; } +// FIXME: should be more like is there a communications relationship, +// since this could be either way +PEP_STATUS has_partner_contacted_address(PEP_SESSION session, const char* partner_id, + const char* own_address, bool* was_contacted) { + + assert(session); + assert(!EMPTYSTR(partner_id)); + assert(!EMPTYSTR(own_address)); + assert(was_contacted); + + if (!session || !was_contacted || EMPTYSTR(partner_id) || EMPTYSTR(own_address)) + return PEP_ILLEGAL_VALUE; + + *was_contacted = false; + + PEP_STATUS status = PEP_STATUS_OK; + + sqlite3_reset(session->has_id_contacted_address); + sqlite3_bind_text(session->has_id_contacted_address, 1, partner_id, -1, + SQLITE_STATIC); + int result = sqlite3_step(session->has_id_contacted_address); + switch (result) { + case SQLITE_ROW: { + // yeah yeah, I know, we could be lazy here, but it looks bad. + *was_contacted = (sqlite3_column_int(session->has_id_contacted_address, 0) != 0); + status = PEP_STATUS_OK; + break; + } + default: + status = PEP_UNKNOWN_DB_ERROR; + } + sqlite3_reset(session->has_id_contacted_address); + + return status; +} + +// FIXME: problematic - can be multiple and this now matters PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session, const pEp_identity* contact, pEp_identity** own_ident) { diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 72bf0e61..040323e0 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -1430,6 +1430,8 @@ PEP_STATUS sign_only(PEP_SESSION session, PEP_STATUS set_all_userids_to_own(PEP_SESSION session, identity_list* id_list); +PEP_STATUS has_partner_contacted_address(PEP_SESSION session, const char* partner_id, + const char* own_address, bool* was_contacted); #ifdef __cplusplus } #endif diff --git a/src/pEp_internal.h b/src/pEp_internal.h index 5d0bde96..20dc2063 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -191,6 +191,7 @@ struct _pEpSession { sqlite3_stmt *set_revoke_contact_as_notified; sqlite3_stmt *get_contacted_ids_from_revoke_fpr; sqlite3_stmt *was_id_for_revoke_contacted; + sqlite3_stmt *has_id_contacted_address; sqlite3_stmt *get_last_contacted; // sqlite3_stmt *set_device_group; // sqlite3_stmt *get_device_group; diff --git a/test/src/KeyResetMessageTest.cc b/test/src/KeyResetMessageTest.cc index fde14f92..c4d3155c 100644 --- a/test/src/KeyResetMessageTest.cc +++ b/test/src/KeyResetMessageTest.cc @@ -307,7 +307,7 @@ TEST_F(KeyResetMessageTest, check_reset_key_and_notify) { ); ASSERT_EQ(int_result , SQLITE_OK); - status = key_reset(session, alice_fpr, from_ident, NULL, NULL); + status = key_reset(session, alice_fpr, from_ident); ASSERT_EQ(status , PEP_STATUS_OK); ASSERT_GT(m_queue.size(), 0); status = myself(session, from_ident); @@ -460,7 +460,7 @@ TEST_F(KeyResetMessageTest, check_receive_message_to_revoked_key_from_unknown) { ASSERT_STRCASEEQ(from_ident->fpr, alice_fpr); ASSERT_TRUE(from_ident->me); - status = key_reset(session, alice_fpr, from_ident, NULL, NULL); + status = key_reset(session, alice_fpr, from_ident); ASSERT_EQ(status , PEP_STATUS_OK); m_queue.clear(); @@ -524,7 +524,7 @@ TEST_F(KeyResetMessageTest, check_receive_message_to_revoked_key_from_contact) { // FIXME: longer term we need to fix the test, but the key attached to the message below has expired, so for now, we give her a new key slurp_and_import_key(session, "test_keys/pub/pep-test-gabrielle-0xE203586C_pub.asc"); - status = key_reset(session, alice_fpr, from_ident, NULL, NULL); + status = key_reset(session, alice_fpr, from_ident); ASSERT_EQ(status , PEP_STATUS_OK); ASSERT_EQ(m_queue.size() , 0); m_queue.clear(); @@ -570,10 +570,10 @@ TEST_F(KeyResetMessageTest, check_multiple_resets_single_key) { ASSERT_STRCASEEQ(from_ident->fpr, alice_fpr); ASSERT_TRUE(from_ident->me); - status = key_reset(session, NULL, NULL, NULL, NULL); + status = key_reset(session, NULL, NULL); ASSERT_EQ(status , PEP_STATUS_OK); - status = key_reset(session, NULL, NULL, NULL, NULL); + status = key_reset(session, NULL, NULL); ASSERT_EQ(status , PEP_STATUS_OK); status = myself(session, from_ident); @@ -1308,7 +1308,7 @@ TEST_F(KeyResetMessageTest, check_reset_mistrust_next_msg_have_not_mailed) { ASSERT_EQ(rating, PEP_rating_reliable); } - +/* TEST_F(KeyResetMessageTest, check_reset_own_with_revocations) { pEp_identity* id1 = new_identity("krista-not-real@darthmama.org", NULL, PEP_OWN_USERID, "Krista at Home"); PEP_STATUS status = myself(session, id1); @@ -1437,7 +1437,7 @@ TEST_F(KeyResetMessageTest, check_reset_own_with_revocations) { ASSERT_EQ(status, PEP_STATUS_OK); } } - +*/ TEST_F(KeyResetMessageTest, codec_test) { // create input values