diff --git a/src/keymanagement.c b/src/keymanagement.c index efc433b7..6abac606 100644 --- a/src/keymanagement.c +++ b/src/keymanagement.c @@ -144,6 +144,19 @@ DYNAMIC_API PEP_STATUS update_identity( /* if we have a stored_identity fpr */ if (!EMPTYSTR(stored_identity->fpr)) { + bool revoked = false; + status = key_revoked(session, stored_identity->fpr, &revoked); + + if (status != PEP_STATUS_OK || revoked) + dont_use_stored_fpr = true; + + if (revoked) { + // Do stuff + status = change_key_comm_type(session, fpr, PEP_ct_key_revoked); + // What to do on failure? FIXME + status = remove_key_as_id_default(session, fpr); + } + status = blacklist_is_listed(session, stored_identity->fpr, &dont_use_stored_fpr); if (status != PEP_STATUS_OK) dont_use_stored_fpr = true; @@ -1048,3 +1061,60 @@ PEP_STATUS contains_priv_key(PEP_SESSION session, const char *fpr, return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private); } + +static PEP_STATUS change_key_comm_type(PEP_SESSION session, + const char* fpr, + PEP_comm_type comm_type) { + + // get all user ids associated with this key + stringlist_t* user_id_list = NULL; + + PEP_STATUS status = get_key_userids(session, fpr, &user_id_list); + + if (status != PEP_STATUS_OK) { + free_stringlist(user_id_list); + return status; + } + + if (!user_id_list || !user_id_list->value()) + return PEP_KEY_NOT_FOUND; + + stringlist_t* curr_id = user_id_list; + + while (curr_id) { + status = set_trust(session, curr_id->value, fpr, comm_type); + if (status != PEP_STATUS_OK) { + free_stringlist(user_id_list); + return status; + } + curr_id = curr_id->next; + } + + return PEP_STATUS_OK; +} + +static PEP_STATUS remove_key_as_id_default(PEP_SESSIONS session, + const char* fpr) +{ + identity_list* affected_ids = NULL; + + PEP_STATUS status get_identities_by_fpr(session, fpr, &identity_list); + + if (status != PEP_STATUS_OK) { + free_identity_list(affected_ids); + return status; + } + if (!affected_ids) + return PEP_STATUS_OK; // it's fine if none are found; + + identity_list* curr_identity = affected_ids; + + while (curr_identity) { + free(curr_identity->fpr); + curr_identity->fpr = (char*)calloc(1, sizeof(char)); // "" + set_identity(session, curr_identity); + curr_identity = curr_identity->next; + } + + +} diff --git a/src/keymanagement.h b/src/keymanagement.h index 64b6c856..4e71f3ef 100644 --- a/src/keymanagement.h +++ b/src/keymanagement.h @@ -159,7 +159,6 @@ DYNAMIC_API PEP_STATUS key_reset_trust( pEp_identity *ident ); - // own_key_is_listed() - returns true id key is listed as own key // // parameters: @@ -241,7 +240,21 @@ DYNAMIC_API PEP_STATUS set_own_key( const char *fpr ); +// change_key_comm_type() - change comm_type for a key already in the trust table +// this impacts any user id associated with this fpr +// parameters: +// session(in) session to use +// fpr(in) fpr for which to change comm_type +static PEP_STATUS change_key_comm_type( + PEP_SESSION session, + const char* fpr + ); + +static PEP_STATUS remove_key_as_id_default( + PEP_SESSIONS session, + const char* fpr + ); + #ifdef __cplusplus } #endif - diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 073446db..13de7525 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -89,6 +89,10 @@ static const char *sql_get_trust = "select comm_type from trust where user_id = ?1 " "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;"; +static const char *sql_get_key_userids = + "select user_id from trust where " + "pgp_keypair_fpr = upper(replace(?1,' ','')) ;"; + static const char *sql_least_trust = "select min(comm_type) from trust where" " pgp_keypair_fpr = upper(replace(?1,' ',''))" @@ -542,6 +546,10 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session) (int)strlen(sql_get_trust), &_session->get_trust, NULL); assert(int_result == SQLITE_OK); + int_result = sqlite3_prepare_v2(_session->db, sql_get_key_userids, + (int)strlen(sql_get_key_userids), &_session->get_key_userids, NULL); + assert(int_result == SQLITE_OK); + int_result = sqlite3_prepare_v2(_session->db, sql_least_trust, (int)strlen(sql_least_trust), &_session->least_trust, NULL); assert(int_result == SQLITE_OK); @@ -749,6 +757,8 @@ DYNAMIC_API void release(PEP_SESSION session) sqlite3_finalize(session->set_trust); if (session->get_trust) sqlite3_finalize(session->get_trust); + if (session->get_key_userids) + sqlite3_finalize(session->get_key_userids); if (session->least_trust) sqlite3_finalize(session->least_trust); if (session->mark_compromized) @@ -1147,13 +1157,15 @@ DYNAMIC_API PEP_STATUS set_identity( identity->user_id && identity->username)) return PEP_ILLEGAL_VALUE; + PEP_STATUS status = PEP_STATUS_OK; + bool listed; bool has_fpr = (identity->fpr && identity->fpr[0] != '\0'); if (has_fpr) { // blacklist check - PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed); + status = blacklist_is_listed(session, identity->fpr, &listed); assert(status == PEP_STATUS_OK); if (status != PEP_STATUS_OK) return status; @@ -1231,6 +1243,8 @@ DYNAMIC_API PEP_STATUS set_identity( } } + status = set_trust(session, identity->user_id, identity->fpr, + identity->comm_type) sqlite3_reset(session->set_trust); sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1, SQLITE_STATIC); @@ -1252,6 +1266,29 @@ DYNAMIC_API PEP_STATUS set_identity( return PEP_COMMIT_FAILED; } +static PEP_STATUS set_trust(PEP_SESSION session, + const char* user_id, + const char* fpr, + PEP_comm_type comm_type) +{ + if (!user_id || !fpr) + return PEP_ILLEGAL_VALUE; + + sqlite3_reset(session->set_trust); + sqlite3_bind_text(session->set_trust, 1, user_id, -1, + SQLITE_STATIC); + sqlite3_bind_text(session->set_trust, 2, fpr, -1, + SQLITE_STATIC); + sqlite3_bind_int(session->set_trust, 3, comm_type); + result = sqlite3_step(session->set_trust); + sqlite3_reset(session->set_trust); + if (result != SQLITE_DONE) { + return PEP_CANNOT_SET_TRUST; + } + + return PEP_STATUS_OK; +} + DYNAMIC_API PEP_STATUS set_device_group( PEP_SESSION session, const char *group_name @@ -1965,6 +2002,74 @@ the_end: return status; } +static PEP_STATUS get_key_userids( + PEP_SESSION session, + const char* fpr, + stringlist_t** keylist + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + assert(fpr); + assert(keylist); + + if (!keylist || !fpr) + return PEP_ILLEGAL_VALUE; + + *keylist = NULL; + + stringlist_t* userid_list = NULL; + + sqlite3_reset(session->get_key_userids); + + int result; + + char* userid; + + do { + userid = NULL; + + result = sqlite3_step(session->get_key_userids); + switch (result) { + case SQLITE_ROW: + userid = (const char *) sqlite3_column_text(session->get_key_userids, + 0); + + if (!userid) + return PEP_UNKNOWN_ERROR; + + if (!userid_list) { + userid_list = new_stringlist(userid); + if (!userid_list) + goto enomem; + } + else { + stringlist_add(userid_list, userid); + } + + break; + + case SQLITE_DONE: + break; + + default: + status = PEP_UNKNOWN_ERROR; + result = SQLITE_DONE; + } + } while (result != SQLITE_DONE); + + sqlite3_reset(session->get_key_userids); + if (status == PEP_STATUS_OK) + *keylist = userid_list; + + goto the_end; + +enomem: + status = PEP_OUT_OF_MEMORY; + +the_end: + return status; +} + DYNAMIC_API PEP_STATUS get_phrase( PEP_SESSION session, const char *lang, @@ -2360,4 +2465,3 @@ DYNAMIC_API void clear_errorstack(PEP_SESSION session) } #endif - diff --git a/src/pEp_internal.h b/src/pEp_internal.h index 77524630..ed9190db 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -109,6 +109,7 @@ struct _pEpSession { sqlite3_stmt *unset_identity_flags; sqlite3_stmt *set_trust; sqlite3_stmt *get_trust; + sqlite3_stmt *get_key_userids; sqlite3_stmt *least_trust; sqlite3_stmt *mark_compromized; sqlite3_stmt *reset_trust; @@ -310,6 +311,10 @@ static inline int _same_fpr( return comparison == 0; } +static PEP_STATUS set_trust(PEP_SESSION session, + const char* user_id, + const char* fpr, + PEP_comm_type comm_type); #ifdef DEBUG_ERRORSTACK PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status);