ENGINE-398: Moved key_reset into its own files

generate_api
Krista Bennett 5 years ago
parent 08d8aa257b
commit 6e4456a1f1

@ -0,0 +1,478 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pEp_internal.h"
#include "dynamic_api.h"
#include "message_api.h"
#include <string.h>
#include <stdlib.h>
PEP_STATUS has_key_reset_been_sent(
PEP_SESSION session,
const char* user_id,
const char* revoked_fpr,
bool* contacted)
{
assert(session);
assert(contacted);
assert(user_id);
assert(revoked_fpr);
assert(!EMPTYSTR(user_id));
if (!session || !contacted || EMPTYSTR(revoked_fpr) || EMPTYSTR(user_id))
return PEP_ILLEGAL_VALUE;
*contacted = false;
char* alias_default = NULL;
PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
free(alias_default);
alias_default = strdup(user_id);
}
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,
SQLITE_STATIC);
int result = sqlite3_step(session->was_id_for_revoke_contacted);
switch (result) {
case SQLITE_ROW: {
*contacted = (sqlite3_column_int(session->was_id_for_revoke_contacted, 0) != 0);
break;
}
default:
sqlite3_reset(session->was_id_for_revoke_contacted);
free(alias_default);
return PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->was_id_for_revoke_contacted);
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* revoke_fpr,
const char* contact_id
)
{
PEP_STATUS status = PEP_STATUS_OK;
assert(session && !EMPTYSTR(revoke_fpr) && !EMPTYSTR(contact_id));
if (!session || 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,
SQLITE_STATIC);
int result;
result = sqlite3_step(session->set_revoke_contact_as_notified);
switch (result) {
case SQLITE_DONE:
status = PEP_STATUS_OK;
break;
default:
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->set_revoke_contact_as_notified);
return status;
}
PEP_STATUS receive_key_reset(PEP_SESSION session,
message* reset_msg) {
if (!session || !reset_msg)
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;
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);
else {
status = PEP_MALFORMED_KEY_RESET_MSG;
goto pep_free;
}
bool own_key = false;
status = is_own_key(session, old_fpr, &own_key);
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;
}
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;
}
new_fpr = strdup(p + 5);
// Reset the original key
status = key_reset(session, old_fpr, temp_ident);
if (status != PEP_STATUS_OK)
goto pep_free;
status = find_keys(session, new_fpr, &keylist);
if (status != PEP_STATUS_OK)
goto pep_free;
if (!keylist) {
status = PEP_KEY_NOT_FOUND;
goto pep_free;
}
// alright, we've checked as best we can. Let's set that baby.
sender_id->fpr = new_fpr;
// 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);
sender_id->fpr = NULL; // ownership for free
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* recip,
const char* old_fpr,
const char* new_fpr) {
if (!dst || !recip->user_id || !recip->address)
return PEP_ILLEGAL_VALUE;
if (!old_fpr || !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);
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");
message* output_msg = NULL;
status = encrypt_message(session, reset_message, 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);
return status;
}
PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
const char* old_fpr,
const char* new_fpr) {
assert(old_fpr);
assert(new_fpr);
assert(session);
assert(session->messageToSend || session->sync_session->messageToSend);
if (!session || !old_fpr || !new_fpr)
return PEP_ILLEGAL_VALUE;
messageToSend_t send_cb = send_cb = session->messageToSend;
void* sync_obj = session->sync_obj;
if (!send_cb) {
send_cb = session->sync_session->messageToSend;
sync_obj = session->sync_session->sync_obj;
}
if (!send_cb)
return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
identity_list* recent_contacts = NULL;
message* reset_msg = NULL;
PEP_STATUS status = get_last_contacted(session, &recent_contacts);
if (status != PEP_STATUS_OK)
goto pep_free;
identity_list* curr_id_ptr = recent_contacts;
for (curr_id_ptr = recent_contacts; curr_id_ptr; curr_id_ptr = curr_id_ptr->next) {
pEp_identity* curr_id = curr_id_ptr->ident;
if (!curr_id)
break;
const char* user_id = curr_id->user_id;
// Should be impossible, but?
if (!user_id)
continue;
// Check if it's us - if so, pointless...
if (is_me(session, curr_id))
continue;
// 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);
if (status != PEP_STATUS_OK)
goto pep_free;
if (contacted)
continue;
// if not, make em a message
reset_msg = NULL;
status = create_standalone_key_reset_message(session,
&reset_msg,
curr_id,
old_fpr,
new_fpr);
if (status == PEP_CANNOT_FIND_IDENTITY) { // this is ok, just means we never mailed them
status = PEP_STATUS_OK;
continue;
}
if (status != PEP_STATUS_OK) {
free(reset_msg);
goto pep_free;
}
// insert into queue
status = send_cb(sync_obj, reset_msg);
if (status != PEP_STATUS_OK) {
free(reset_msg);
goto pep_free;
}
// Put into notified DB
status = set_reset_contact_notified(session, old_fpr, user_id);
if (status != PEP_STATUS_OK)
goto pep_free;
}
pep_free:
free_identity_list(recent_contacts);
return status;
}
DYNAMIC_API PEP_STATUS key_reset(
PEP_SESSION session,
const char* key_id,
pEp_identity* ident
)
{
if (!session)
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
char* fpr_copy = NULL;
char* own_id = NULL;
char* new_key = NULL;
identity_list* key_idents = NULL;
stringlist_t* keys = NULL;
if (!EMPTYSTR(key_id)) {
fpr_copy = strdup(key_id);
if (!fpr_copy)
return PEP_OUT_OF_MEMORY;
}
if (!ident) {
// Get list of own identities
status = get_default_own_userid(session, &own_id);
if (status != PEP_STATUS_OK)
goto pep_free;
if (EMPTYSTR(fpr_copy)) {
status = get_all_keys_for_user(session, own_id, &keys);
if (status == PEP_STATUS_OK) {
stringlist_t* curr_key;
for (curr_key = keys; curr_key && curr_key->value; curr_key = curr_key->next) {
status = key_reset(session, curr_key->value, NULL);
if (status != PEP_STATUS_OK)
break;
}
}
goto pep_free;
} // otherwise, we have a specific fpr to process
// fpr_copy exists, so... let's go.
// Process own identities with this fpr
status = get_identities_by_main_key_id(session, fpr_copy, &key_idents);
if (status == PEP_STATUS_OK) {
// 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;
status = key_reset(session, fpr_copy, this_identity);
if (status != PEP_STATUS_OK)
break;
}
}
goto pep_free;
}
else { // an identity was specified.
if (is_me(session, ident)) {
// FIXME: make sure this IS our fpr?
// If it got sent in with an empty fpr...
if (EMPTYSTR(fpr_copy)) {
//
// if (!EMPTYSTR(ident->fpr))
// fpr_copy = strdup(ident->fpr);
status = _myself(session, ident, false, true);
if (status == PEP_STATUS_OK && ident->fpr)
fpr_copy = strdup(ident->fpr);
else {
// last resort?
// Get list of own identities
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (status == PEP_STATUS_OK)
status = get_user_default_key(session, own_id, &fpr_copy);
if (status != PEP_STATUS_OK || EMPTYSTR(fpr_copy)) {
free(own_id);
return (status == PEP_STATUS_OK ? PEP_KEY_NOT_FOUND : status);
}
}
}
free(ident->fpr);
ident->fpr = fpr_copy;
// Create revocation
status = revoke_key(session, fpr_copy, NULL);
// generate new key
if (status == PEP_STATUS_OK) {
ident->fpr = NULL;
status = generate_keypair(session, ident);
}
if (status == PEP_STATUS_OK) {
new_key = strdup(ident->fpr);
status = set_own_key(session, ident, new_key);
}
// mistrust fpr from trust
ident->fpr = fpr_copy;
ident->comm_type = PEP_ct_mistrusted;
status = set_trust(session, ident);
ident->fpr = NULL;
// Done with old use of ident.
if (status == PEP_STATUS_OK) {
// Update fpr for outgoing
status = myself(session, ident);
}
if (status == PEP_STATUS_OK)
// cascade that mistrust for anyone using this key
status = mark_as_compromised(session, fpr_copy);
if (status == PEP_STATUS_OK)
status = remove_fpr_as_default(session, fpr_copy);
if (status == PEP_STATUS_OK)
status = add_mistrusted_key(session, fpr_copy);
// add to revocation list
if (status == PEP_STATUS_OK)
status = set_revoked(session, fpr_copy, new_key, time(NULL));
// for all active communication partners:
// active_send revocation
if (status == PEP_STATUS_OK)
status = send_key_reset_to_recents(session, fpr_copy, new_key);
}
else { // not is_me
// remove fpr from all identities
// remove fpr from all users
if (status == PEP_STATUS_OK)
status = remove_fpr_as_default(session, fpr_copy);
// delete key from DB
if (status == PEP_STATUS_OK) {};
// status = delete_keypair(session, fpr_copy);
// N.B. If this key is being replaced by something else, it
// is done outside of this function.
}
}
pep_free:
free(fpr_copy);
free(own_id);
free_identity_list(key_idents);
free_stringlist(keys);
free(new_key);
return status;
}

@ -0,0 +1,93 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#pragma once
#include "key_reset.h"
#include "pEpEngine.h"
#include "keymanagement.h"
#include "message.h"
#include "message_api.h"
#include "cryptotech.h"
#ifdef __cplusplus
extern "C" {
#endif
// FIXME: Proper docs!
// Algorithm:
//
// Key Reset trigger; either manually or in another protocol, parameter key (optional)
//
// if identity given:
//
// key reset for one identity
//
// else
//
// For identity in own identities
//
// key reset for one identitiy
//
// Key Reset for identity:
//
// if own identity:
//
// Create revocation
//
// add to revocation list
//
// mistrust fpr from trust
//
// Remove fpr from ALL identities
//
// Remove fpr from ALL users
//
// generate new key
//
// for all active communication partners:
//
// active_send revocation
//
// else
//
// remove fpr from all identities
//
// remove fpr from all users
//
// delete key from key ring
DYNAMIC_API PEP_STATUS key_reset(
PEP_SESSION session,
const char* fpr,
pEp_identity* ident
);
PEP_STATUS has_key_reset_been_sent(
PEP_SESSION session,
const char* user_id,
const char* revoked_fpr,
bool* contacted);
PEP_STATUS set_reset_contact_notified(
PEP_SESSION session,
const char* revoke_fpr,
const char* contact_id
);
PEP_STATUS receive_key_reset(PEP_SESSION session,
message* reset_msg);
PEP_STATUS create_standalone_key_reset_message(PEP_SESSION session,
message** dst,
pEp_identity* recip,
const char* old_fpr,
const char* new_fpr);
PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
const char* old_fpr,
const char* new_fpr);
#ifdef __cplusplus
}
#endif

@ -1547,153 +1547,6 @@ void attach_own_key(PEP_SESSION session, message *msg)
free(revoked_fpr);
}
PEP_STATUS create_standalone_key_reset_message(PEP_SESSION session,
message** dst,
pEp_identity* recip,
const char* old_fpr,
const char* new_fpr) {
if (!dst || !recip->user_id || !recip->address)
return PEP_ILLEGAL_VALUE;
if (!old_fpr || !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);
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");
message* output_msg = NULL;
status = encrypt_message(session, reset_message, 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);
return status;
}
PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
const char* old_fpr,
const char* new_fpr) {
assert(old_fpr);
assert(new_fpr);
assert(session);
assert(session->messageToSend || session->sync_session->messageToSend);
if (!session || !old_fpr || !new_fpr)
return PEP_ILLEGAL_VALUE;
messageToSend_t send_cb = send_cb = session->messageToSend;
void* sync_obj = session->sync_obj;
if (!send_cb) {
send_cb = session->sync_session->messageToSend;
sync_obj = session->sync_session->sync_obj;
}
if (!send_cb)
return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
identity_list* recent_contacts = NULL;
message* reset_msg = NULL;
PEP_STATUS status = get_last_contacted(session, &recent_contacts);
if (status != PEP_STATUS_OK)
goto pep_free;
identity_list* curr_id_ptr = recent_contacts;
for (curr_id_ptr = recent_contacts; curr_id_ptr; curr_id_ptr = curr_id_ptr->next) {
pEp_identity* curr_id = curr_id_ptr->ident;
if (!curr_id)
break;
const char* user_id = curr_id->user_id;
// Should be impossible, but?
if (!user_id)
continue;
// Check if it's us - if so, pointless...
if (is_me(session, curr_id))
continue;
// 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);
if (status != PEP_STATUS_OK)
goto pep_free;
if (contacted)
continue;
// if not, make em a message
reset_msg = NULL;
status = create_standalone_key_reset_message(session,
&reset_msg,
curr_id,
old_fpr,
new_fpr);
if (status == PEP_CANNOT_FIND_IDENTITY) { // this is ok, just means we never mailed them
status = PEP_STATUS_OK;
continue;
}
if (status != PEP_STATUS_OK) {
free(reset_msg);
goto pep_free;
}
// insert into queue
status = send_cb(sync_obj, reset_msg);
if (status != PEP_STATUS_OK) {
free(reset_msg);
goto pep_free;
}
// Put into notified DB
status = set_reset_contact_notified(session, old_fpr, user_id);
if (status != PEP_STATUS_OK)
goto pep_free;
}
pep_free:
free_identity_list(recent_contacts);
return status;
}
PEP_cryptotech determine_encryption_format(message *msg)
{
assert(msg);
@ -3290,86 +3143,6 @@ pep_free:
}
PEP_STATUS receive_key_reset(PEP_SESSION session,
message* reset_msg) {
if (!session || !reset_msg)
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;
// FIXME: We'll have to change this for lists!!!
if (is_me(session, sender_id)) // hrm...
return PEP_ILLEGAL_VALUE;
if (!reset_msg->longmsg || strncmp(reset_msg->longmsg, "OLD: ", 5) != 0)
return PEP_MALFORMED_KEY_RESET_MSG;
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);
else {
status = PEP_MALFORMED_KEY_RESET_MSG;
goto pep_free;
}
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;
}
new_fpr = strdup(p + 5);
// Reset the original key
status = key_reset(session, old_fpr, temp_ident);
if (status != PEP_STATUS_OK)
goto pep_free;
status = find_keys(session, new_fpr, &keylist);
if (status != PEP_STATUS_OK)
goto pep_free;
if (!keylist) {
status = PEP_KEY_NOT_FOUND;
goto pep_free;
}
// alright, we've checked as best we can. Let's set that baby.
sender_id->fpr = new_fpr;
// 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);
sender_id->fpr = NULL; // ownership for free
pep_free:
free_stringlist(keylist);
free(old_fpr);
free(new_fpr);
free_identity(temp_ident);
return status;
}
DYNAMIC_API PEP_STATUS _decrypt_message(
PEP_SESSION session,
message *src,
@ -3957,156 +3730,6 @@ DYNAMIC_API PEP_STATUS own_message_private_key_details(
return status;
}
DYNAMIC_API PEP_STATUS key_reset(
PEP_SESSION session,
const char* key_id,
pEp_identity* ident
)
{
if (!session)
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
char* fpr_copy = NULL;
char* own_id = NULL;
char* new_key = NULL;
identity_list* key_idents = NULL;
stringlist_t* keys = NULL;
if (!EMPTYSTR(key_id)) {
fpr_copy = strdup(key_id);
if (!fpr_copy)
return PEP_OUT_OF_MEMORY;
}
if (!ident) {
// Get list of own identities
status = get_default_own_userid(session, &own_id);
if (status != PEP_STATUS_OK)
goto pep_free;
if (EMPTYSTR(fpr_copy)) {
status = get_all_keys_for_user(session, own_id, &keys);
if (status == PEP_STATUS_OK) {
stringlist_t* curr_key;
for (curr_key = keys; curr_key && curr_key->value; curr_key = curr_key->next) {
status = key_reset(session, curr_key->value, NULL);
if (status != PEP_STATUS_OK)
break;
}
}
goto pep_free;
} // otherwise, we have a specific fpr to process
// fpr_copy exists, so... let's go.
// Process own identities with this fpr
status = get_identities_by_main_key_id(session, fpr_copy, &key_idents);
if (status == PEP_STATUS_OK) {
// 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;
status = key_reset(session, fpr_copy, this_identity);
if (status != PEP_STATUS_OK)
break;
}
}
goto pep_free;
}
else { // an identity was specified.
if (is_me(session, ident)) {
// FIXME: make sure this IS our fpr?
// If it got sent in with an empty fpr...
if (EMPTYSTR(fpr_copy)) {
//
// if (!EMPTYSTR(ident->fpr))
// fpr_copy = strdup(ident->fpr);
status = _myself(session, ident, false, true);
if (status == PEP_STATUS_OK && ident->fpr)
fpr_copy = strdup(ident->fpr);
else {
// last resort?
// Get list of own identities
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (status == PEP_STATUS_OK)
status = get_user_default_key(session, own_id, &fpr_copy);
if (status != PEP_STATUS_OK || EMPTYSTR(fpr_copy)) {
free(own_id);
return (status == PEP_STATUS_OK ? PEP_KEY_NOT_FOUND : status);
}
}
}
free(ident->fpr);
ident->fpr = fpr_copy;
// Create revocation
status = revoke_key(session, fpr_copy, NULL);
// generate new key
if (status == PEP_STATUS_OK) {
ident->fpr = NULL;
status = generate_keypair(session, ident);
}
if (status == PEP_STATUS_OK) {
new_key = strdup(ident->fpr);
status = set_own_key(session, ident, new_key);
}
// mistrust fpr from trust
ident->fpr = fpr_copy;
ident->comm_type = PEP_ct_mistrusted;
status = set_trust(session, ident);
ident->fpr = NULL;
// Done with old use of ident.
if (status == PEP_STATUS_OK) {
// Update fpr for outgoing
status = myself(session, ident);
}
if (status == PEP_STATUS_OK)
// cascade that mistrust for anyone using this key
status = mark_as_compromised(session, fpr_copy);
if (status == PEP_STATUS_OK)
status = remove_fpr_as_default(session, fpr_copy);
if (status == PEP_STATUS_OK)
status = add_mistrusted_key(session, fpr_copy);
// add to revocation list
if (status == PEP_STATUS_OK)
status = set_revoked(session, fpr_copy, new_key, time(NULL));
// for all active communication partners:
// active_send revocation
if (status == PEP_STATUS_OK)
status = send_key_reset_to_recents(session, fpr_copy, new_key);
}
else { // not is_me
// remove fpr from all identities
// remove fpr from all users
if (status == PEP_STATUS_OK)
status = remove_fpr_as_default(session, fpr_copy);
// delete key from DB
if (status == PEP_STATUS_OK) {};
// status = delete_keypair(session, fpr_copy);
// N.B. If this key is being replaced by something else, it
// is done outside of this function.
}
}
pep_free:
free(fpr_copy);
free(own_id);
free_identity_list(key_idents);
free_stringlist(keys);
free(new_key);
return status;
}
// Note: if comm_type_determine is false, it generally means that
// we were unable to get key information for anyone in the list,
// likely because a key is missing.

@ -4366,92 +4366,6 @@ PEP_STATUS get_last_contacted(
}
PEP_STATUS has_key_reset_been_sent(
PEP_SESSION session,
const char* user_id,
const char* revoked_fpr,
bool* contacted)
{
assert(session);
assert(contacted);
assert(user_id);
assert(revoked_fpr);
assert(!EMPTYSTR(user_id));
if (!session || !contacted || EMPTYSTR(revoked_fpr) || EMPTYSTR(user_id))
return PEP_ILLEGAL_VALUE;
*contacted = false;
char* alias_default = NULL;
PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
free(alias_default);
alias_default = strdup(user_id);
}
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,
SQLITE_STATIC);
int result = sqlite3_step(session->was_id_for_revoke_contacted);
switch (result) {
case SQLITE_ROW: {
*contacted = (sqlite3_column_int(session->was_id_for_revoke_contacted, 0) != 0);
break;
}
default:
sqlite3_reset(session->was_id_for_revoke_contacted);
free(alias_default);
return PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->was_id_for_revoke_contacted);
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* revoke_fpr,
const char* contact_id
)
{
PEP_STATUS status = PEP_STATUS_OK;
assert(session && !EMPTYSTR(revoke_fpr) && !EMPTYSTR(contact_id));
if (!session || 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,
SQLITE_STATIC);
int result;
result = sqlite3_step(session->set_revoke_contact_as_notified);
switch (result) {
case SQLITE_DONE:
status = PEP_STATUS_OK;
break;
default:
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->set_revoke_contact_as_notified);
return status;
}
PEP_STATUS key_created(
PEP_SESSION session,
const char *fpr,

@ -1177,54 +1177,6 @@ DYNAMIC_API PEP_STATUS get_revoked(
uint64_t *revocation_date
);
// Algorithm:
//
// Key Reset trigger; either manually or in another protocol, parameter key (optional)
//
// if identity given:
//
// key reset for one identity
//
// else
//
// For identity in own identities
//
// key reset for one identitiy
//
// Key Reset for identity:
//
// if own identity:
//
// Create revocation
//
// add to revocation list
//
// mistrust fpr from trust
//
// Remove fpr from ALL identities
//
// Remove fpr from ALL users
//
// generate new key
//
// for all active communication partners:
//
// active_send revocation
//
// else
//
// remove fpr from all identities
//
// remove fpr from all users
//
// delete key from key ring
DYNAMIC_API PEP_STATUS key_reset(
PEP_SESSION session,
const char* fpr,
pEp_identity* ident
);
// key_created() - get creation date of a key
//
// parameters:
@ -1349,19 +1301,6 @@ PEP_STATUS get_last_contacted(
identity_list** id_list
);
PEP_STATUS has_key_reset_been_sent(
PEP_SESSION session,
const char* user_id,
const char* revoked_fpr,
bool* contacted);
PEP_STATUS set_reset_contact_notified(
PEP_SESSION session,
const char* revoke_fpr,
const char* contact_id
);
PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session,
const pEp_identity* contact,
pEp_identity** own_ident);

@ -108,6 +108,8 @@
#include "transport.h"
#include "sync.h"
#include "key_reset.h"
#define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
struct _pEpSession;

@ -0,0 +1,87 @@
Message-ID: <pEp.PEW827.18NQTABD97IHX.3E6116A3-906D-4DAD-8BDD-3381606B4302@pep-project.org>
From: Gabi <pep-test-gabrielle@pep-project.org>
To: Alice is tired of Bob <pep.test.alice@pep-project.org>
Subject: =?utf-8?Q?p=E2=89=A1p?=
X-pEp-Version: 2.0
MIME-Version: 1.0
Content-Type: multipart/encrypted; boundary="d39e5287be3847623f45c9767504e45";
protocol="application/pgp-encrypted"
--d39e5287be3847623f45c9767504e45
Content-Type: application/pgp-encrypted
Version: 1
--d39e5287be3847623f45c9767504e45
Content-Type: application/octet-stream
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="msg.asc"
-----BEGIN PGP MESSAGE-----
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
6ihY
=/YtR
-----END PGP MESSAGE-----
--d39e5287be3847623f45c9767504e45--

@ -0,0 +1,115 @@
From: Alice in Wonderland <pep.test.alice@pep-project.org>
To: Bob's Burgers <pep.test.bob@pep-project.org>
Subject: =?utf-8?Q?p=E2=89=A1p?=
X-pEp-Version: 2.0
MIME-Version: 1.0
Content-Type: multipart/encrypted; boundary="41fb875950ea35e61360a605caa7977";
protocol="application/pgp-encrypted"
--41fb875950ea35e61360a605caa7977
Content-Type: application/pgp-encrypted
Version: 1
--41fb875950ea35e61360a605caa7977
Content-Type: application/octet-stream
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="msg.asc"
-----BEGIN PGP MESSAGE-----
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
ICgsOg1vvjXDZLqEyHrjxMCHpZiCNBksnQ==
=0apO
-----END PGP MESSAGE-----
--41fb875950ea35e61360a605caa7977--

@ -0,0 +1,121 @@
Message-ID: <pEp.PEW17L.0RC7XPI9ZPB8X.97B39B40-10C2-404B-B8CC-54B79229F8FD@pep-project.org>
From: Alice in Wonderland <pep.test.alice@pep-project.org>
To: Fenris Leto Hawke <pep.test.fenris@thisstilldoesntwork.lu>
Subject: =?utf-8?Q?p=E2=89=A1p?=
X-pEp-Version: 2.0
MIME-Version: 1.0
Content-Type: multipart/encrypted; boundary="7e23a74c7397f0666f31d87d17b86a89";
protocol="application/pgp-encrypted"
--7e23a74c7397f0666f31d87d17b86a89
Content-Type: application/pgp-encrypted
Version: 1
--7e23a74c7397f0666f31d87d17b86a89
Content-Type: application/octet-stream
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="msg.asc"
-----BEGIN PGP MESSAGE-----
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
Gbdayy1g6mwuZA==
=ncTl
-----END PGP MESSAGE-----
--7e23a74c7397f0666f31d87d17b86a89--
Loading…
Cancel
Save