Browse Source

ENGINE-398:key_reset in, and compiling again.

generate_api
Krista Bennett 4 years ago
parent
commit
886f8bb94a
7 changed files with 450 additions and 15 deletions
  1. +37
    -0
      src/keymanagement.c
  2. +5
    -0
      src/keymanagement.h
  3. +151
    -11
      src/message_api.c
  4. +194
    -1
      src/pEpEngine.c
  5. +58
    -0
      src/pEpEngine.h
  6. +5
    -1
      src/pEp_internal.h
  7. +0
    -2
      src/pgp_gpg.c

+ 37
- 0
src/keymanagement.c View File

@ -233,6 +233,43 @@ static PEP_STATUS validate_fpr(PEP_SESSION session,
return status;
}
PEP_STATUS get_all_keys_for_user(PEP_SESSION session,
const char* user_id,
stringlist_t** keys) {
if (!session || EMPTYSTR(user_id) || !keys)
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
*keys = NULL;
stringlist_t* _kl = NULL;
sqlite3_reset(session->get_all_keys_for_user);
sqlite3_bind_text(session->get_all_keys_for_user, 1, user_id, -1, SQLITE_STATIC);
int result = -1;
while ((result = sqlite3_step(session->get_all_keys_for_user)) == SQLITE_ROW) {
const char* keyres = (const char *) sqlite3_column_text(session->get_all_keys_for_user, 0);
if (keyres) {
if (_kl)
stringlist_add(_kl, keyres);
else
_kl = new_stringlist(keyres);
}
}
if (!_kl)
return PEP_KEY_NOT_FOUND;
*keys = _kl;
sqlite3_reset(session->get_all_keys_for_user);
return status;
}
PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
char** default_key) {
assert(session);


+ 5
- 0
src/keymanagement.h View File

@ -358,6 +358,11 @@ DYNAMIC_API PEP_STATUS set_own_key(
const char *fpr
);
PEP_STATUS get_all_keys_for_user(PEP_SESSION session,
const char* user_id,
stringlist_t** keys);
PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr);


+ 151
- 11
src/message_api.c View File

@ -1580,9 +1580,15 @@ PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
if (!session || !revoke_fpr || !new_fpr)
return PEP_ILLEGAL_VALUE;
if (!session->sync_session->inject_sync_msg || session->sync_session->sync_management)
return PEP_SYNC_NO_INJECT_CALLBACK;
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;
@ -1594,7 +1600,6 @@ PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
identity_list* curr_id_ptr = recent_contacts;
while (curr_id_ptr) {
pEp_identity* curr_id = curr_id_ptr->ident;
@ -1629,12 +1634,10 @@ PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
goto pep_free;
// insert into queue
int result = session->sync_session->inject_sync_msg(reset_msg, session->sync_session->sync_management);
status = send_cb(sync_obj, reset_msg);
if (result != 0) {
status = PEP_SYNC_INJECT_FAILED;
if (status != PEP_STATUS_OK)
goto pep_free;
}
// Put into notified DB
status = set_reset_contact_notified(session, revoke_fpr, user_id);
@ -3294,7 +3297,7 @@ PEP_STATUS receive_key_reset(PEP_SESSION session,
goto pep_free;
}
// Before we go further, let's be sure this was signed be the revoked fpr.
// Before we go further, let's be sure this was signed by the revoked fpr.
if (strcasecmp(revoke_fpr, signing_fpr) != 0) {
status = PEP_ILLEGAL_VALUE;
goto pep_free;
@ -3329,8 +3332,7 @@ PEP_STATUS receive_key_reset(PEP_SESSION session,
}
// We know that the signer has the sender's user_id, and that the revoked fpr
// is theirs. We now need to make sure that we've imported the key we need.
// is theirs. We now need to make sure that we've imported the key we need.
status = find_keys(session, new_fpr, &keylist);
if (status != PEP_STATUS_OK)
goto pep_free;
@ -3345,6 +3347,7 @@ PEP_STATUS receive_key_reset(PEP_SESSION session,
sender_id->comm_type = sender_id->comm_type & (~PEP_ct_confirmed);
status = set_identity(session, sender_id);
if (status == PEP_STATUS_OK)
status = PEP_KEY_RESET_SUCCESSFUL;
@ -3942,6 +3945,143 @@ 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 = NULL;
char* own_id = NULL;
identity_list* key_idents = NULL;
stringlist_t* keys = NULL;
if (key_id) {
fpr = strdup(key_id);
if (!fpr)
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) {
free(fpr);
return status;
}
if (fpr)
status = get_identities_by_main_key_id(session, fpr, &key_idents);
else {
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;
}
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, this_identity);
if (status != PEP_STATUS_OK)
break;
}
}
goto pep_free;
}
else {
if (is_me(session, ident)) {
// FIXME: make sure this IS our fpr?
if (!fpr) {
if (ident->fpr)
fpr = strdup(ident->fpr);
else {
// Note: this will choke if we've already revoked. Is that
// Ok? Or do we need per-identity revokes? Best practice
// is to always send in a damned fpr! ;)
status = _myself(session, ident, false, true);
if (status == PEP_STATUS_OK && ident->fpr) {
fpr = 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);
if (status != PEP_STATUS_OK || !fpr) {
free(own_id);
return (status == PEP_STATUS_OK ? PEP_KEY_NOT_FOUND : status);
}
}
}
}
// We now have an fpr. Be careful - it may have been an input fpr,
// and it may be connected to the ident
char* fpr_backup = ident->fpr;
ident->fpr = fpr;
// Create revocation
status = revoke_key(session, fpr, NULL);
// mistrust fpr from trust
if (status == PEP_STATUS_OK)
status = key_mistrusted(session, ident);
// Remove fpr from ALL identities
// Remove fpr from ALL users
if (status == PEP_STATUS_OK)
status = remove_fpr_as_default(session, ident->fpr);
if (status == PEP_STATUS_OK)
status = add_mistrusted_key(session, ident->fpr);
// generate new key
if (status == PEP_STATUS_OK)
status = generate_keypair(session, ident);
// add to revocation list
if (status == PEP_STATUS_OK)
status = set_revoked(session, fpr, ident->fpr, time(NULL));
// for all active communication partners:
// active_send revocation
if (status == PEP_STATUS_OK)
status = send_key_reset_to_recents(session, fpr, ident->fpr);
ident->fpr = fpr_backup;
}
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);
// delete key from key ring
if (status == PEP_STATUS_OK)
status = delete_keypair(session, fpr);
// N.B. If this key is being replaced by something else, it
// is done outside of this function.
}
}
pep_free:
free(fpr);
free(own_id);
free_identity_list(key_idents);
free_stringlist(keys);
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.


+ 194
- 1
src/pEpEngine.c View File

@ -97,6 +97,32 @@ static const char *sql_get_identity =
" order by is_own desc, "
" timestamp desc; ";
static const char *sql_get_identities_by_userid =
"select address, fpr, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags,"
" is_own"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
" join trust on id = trust.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where identity.user_id = ?1"
" order by is_own desc, "
" timestamp desc; ";
static const char *sql_get_identities_by_main_key_id =
"select address, user_id, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags,"
" is_own"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
" join trust on id = trust.user_id"
" and pgp_keypair_fpr = identity.main_key_id"
" where main_key_id = ?1"
" order by is_own desc, "
" timestamp desc; ";
static const char *sql_get_identity_without_trust_check =
"select identity.main_key_id, username, lang,"
" identity.flags, is_own"
@ -372,6 +398,10 @@ static const char* sql_get_user_default_key =
"select main_key_id from person"
" where id = ?1;";
static const char* sql_get_all_keys_for_user =
"select pgp_keypair_fpr from trust"
" where user_id = ?1; ";
static const char* sql_get_default_own_userid =
"select id from person"
" join identity on id = identity.user_id"
@ -1141,10 +1171,24 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
&_session->get_identities_by_address, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_userid,
(int)strlen(sql_get_identities_by_userid),
&_session->get_identities_by_userid, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_main_key_id,
(int)strlen(sql_get_identities_by_main_key_id),
&_session->get_identities_by_main_key_id, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
(int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_all_keys_for_user,
(int)strlen(sql_get_all_keys_for_user), &_session->get_all_keys_for_user, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
(int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
assert(int_result == SQLITE_OK);
@ -1493,8 +1537,14 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->get_identity_without_trust_check);
if (session->get_identities_by_address)
sqlite3_finalize(session->get_identities_by_address);
if (session->get_identities_by_userid)
sqlite3_finalize(session->get_identities_by_userid);
if (session->get_identities_by_main_key_id)
sqlite3_finalize(session->get_identities_by_main_key_id);
if (session->get_user_default_key)
sqlite3_finalize(session->get_user_default_key);
sqlite3_finalize(session->get_user_default_key);
if (session->get_all_keys_for_user)
sqlite3_finalize(session->get_all_keys_for_user);
if (session->get_default_own_userid)
sqlite3_finalize(session->get_default_own_userid);
if (session->get_userid_alias_default)
@ -2108,6 +2158,149 @@ DYNAMIC_API PEP_STATUS get_identity(
return status;
}
PEP_STATUS get_identities_by_userid(
PEP_SESSION session,
const char *user_id,
identity_list **identities
)
{
if (!session || !identities || EMPTYSTR(user_id))
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
pEp_identity* ident = NULL;
*identities = new_identity_list(NULL);
sqlite3_reset(session->get_identities_by_userid);
sqlite3_bind_text(session->get_identities_by_userid, 1, user_id, -1, SQLITE_STATIC);
int result = -1;
while ((result = sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
// "select address, fpr, username, comm_type, lang,"
// " identity.flags | pgp_keypair.flags,"
// " is_own"
// " from identity"
// " join person on id = identity.user_id"
// " join pgp_keypair on fpr = identity.main_key_id"
// " join trust on id = trust.user_id"
// " and pgp_keypair_fpr = identity.main_key_id"
// " where identity.user_id = ?1"
// " order by is_own desc, "
// " timestamp desc; ";
ident = new_identity(
(const char *) sqlite3_column_text(session->get_identities_by_userid, 0),
(const char *) sqlite3_column_text(session->get_identities_by_userid, 1),
user_id,
(const char *) sqlite3_column_text(session->get_identities_by_userid, 2)
);
assert(ident);
if (ident == NULL) {
sqlite3_reset(session->get_identities_by_userid);
return PEP_OUT_OF_MEMORY;
}
ident->comm_type = (PEP_comm_type)
sqlite3_column_int(session->get_identities_by_userid, 3);
const char* const _lang = (const char *)
sqlite3_column_text(session->get_identities_by_userid, 4);
if (_lang && _lang[0]) {
assert(_lang[0] >= 'a' && _lang[0] <= 'z');
assert(_lang[1] >= 'a' && _lang[1] <= 'z');
assert(_lang[2] == 0);
ident->lang[0] = _lang[0];
ident->lang[1] = _lang[1];
ident->lang[2] = 0;
}
ident->flags = (unsigned int)
sqlite3_column_int(session->get_identities_by_userid, 5);
ident->me = (unsigned int)
sqlite3_column_int(session->get_identities_by_userid, 6);
identity_list_add(*identities, ident);
ident = NULL;
}
if ((*identities)->ident == NULL) {
free_identity_list(*identities);
*identities = NULL;
status = PEP_CANNOT_FIND_IDENTITY;
}
sqlite3_reset(session->get_identities_by_userid);
return status;
}
PEP_STATUS get_identities_by_main_key_id(
PEP_SESSION session,
const char *fpr,
identity_list **identities
)
{
if (!session || !identities || EMPTYSTR(fpr))
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
pEp_identity* ident = NULL;
*identities = new_identity_list(NULL);
sqlite3_reset(session->get_identities_by_main_key_id);
sqlite3_bind_text(session->get_identities_by_main_key_id, 1, fpr, -1, SQLITE_STATIC);
int result = -1;
while ((result = sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
ident = new_identity(
(const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 0),
fpr,
(const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 1),
(const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 2)
);
assert(ident);
if (ident == NULL) {
sqlite3_reset(session->get_identities_by_main_key_id);
return PEP_OUT_OF_MEMORY;
}
ident->comm_type = (PEP_comm_type)
sqlite3_column_int(session->get_identities_by_main_key_id, 3);
const char* const _lang = (const char *)
sqlite3_column_text(session->get_identities_by_main_key_id, 4);
if (_lang && _lang[0]) {
assert(_lang[0] >= 'a' && _lang[0] <= 'z');
assert(_lang[1] >= 'a' && _lang[1] <= 'z');
assert(_lang[2] == 0);
ident->lang[0] = _lang[0];
ident->lang[1] = _lang[1];
ident->lang[2] = 0;
}
ident->flags = (unsigned int)
sqlite3_column_int(session->get_identities_by_main_key_id, 5);
ident->me = (unsigned int)
sqlite3_column_int(session->get_identities_by_main_key_id, 6);
identity_list_add(*identities, ident);
ident = NULL;
}
if ((*identities)->ident == NULL) {
free_identity_list(*identities);
*identities = NULL;
status = PEP_CANNOT_FIND_IDENTITY;
}
sqlite3_reset(session->get_identities_by_main_key_id);
return status;
}
PEP_STATUS get_identity_without_trust_check(
PEP_SESSION session,
const char *address,


+ 58
- 0
src/pEpEngine.h View File

@ -1178,6 +1178,53 @@ 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
//
@ -1255,6 +1302,12 @@ PEP_STATUS get_identities_by_address(
const char *address,
identity_list** id_list
);
PEP_STATUS get_identities_by_userid(
PEP_SESSION session,
const char *user_id,
identity_list **identities
);
PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
const char* new_uid);
@ -1315,6 +1368,11 @@ PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
PEP_STATUS is_own_key(PEP_SESSION session, const char* fpr, bool* own_key);
PEP_STATUS get_identities_by_main_key_id(
PEP_SESSION session,
const char *fpr,
identity_list **identities);
#ifdef __cplusplus
}
#endif

+ 5
- 1
src/pEp_internal.h View File

@ -131,6 +131,8 @@ struct _pEpSession {
sqlite3_stmt *get_identity;
sqlite3_stmt *get_identity_without_trust_check;
sqlite3_stmt *get_identities_by_address;
sqlite3_stmt *get_identities_by_userid;
sqlite3_stmt *get_identities_by_main_key_id;
sqlite3_stmt *replace_identities_fpr;
sqlite3_stmt *replace_main_user_fpr;
sqlite3_stmt *get_main_user_fpr;
@ -175,14 +177,16 @@ struct _pEpSession {
sqlite3_stmt *blacklist_is_listed;
sqlite3_stmt *blacklist_retrieve;
// Own keys
// Keys
sqlite3_stmt *own_key_is_listed;
sqlite3_stmt *own_identities_retrieve;
sqlite3_stmt *own_keys_retrieve;
sqlite3_stmt *get_user_default_key;
sqlite3_stmt *get_all_keys_for_user;
sqlite3_stmt *get_default_own_userid;
// sqlite3_stmt *set_own_key;
// sequence value


+ 0
- 2
src/pgp_gpg.c View File

@ -298,8 +298,6 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
gpgme = dlopen(LIBGPGME, RTLD_LAZY);
if (gpgme == NULL) {
// FIXME: Hotfix here?
status = PEP_INIT_CANNOT_LOAD_GPGME;
goto pep_error;
}


Loading…
Cancel
Save