ENGINE-398:key_reset in, and compiling again. ENGINE-398
authorKrista Bennett <krista@pep-project.org>
Mon, 27 Aug 2018 15:15:59 +0200
branchENGINE-398
changeset 2893fb7580af7822
parent 2892 033f13ec8c24
child 2917 51f4afe41dcb
ENGINE-398:key_reset in, and compiling again.
src/keymanagement.c
src/keymanagement.h
src/message_api.c
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/pgp_gpg.c
     1.1 --- a/src/keymanagement.c	Wed Aug 22 14:55:43 2018 +0200
     1.2 +++ b/src/keymanagement.c	Mon Aug 27 15:15:59 2018 +0200
     1.3 @@ -233,6 +233,43 @@
     1.4      return status;
     1.5  }
     1.6  
     1.7 +PEP_STATUS get_all_keys_for_user(PEP_SESSION session, 
     1.8 +                                 const char* user_id,
     1.9 +                                 stringlist_t** keys) {
    1.10 +
    1.11 +    if (!session || EMPTYSTR(user_id) || !keys)
    1.12 +        return PEP_ILLEGAL_VALUE;
    1.13 +        
    1.14 +    PEP_STATUS status = PEP_STATUS_OK;
    1.15 +        
    1.16 +    *keys = NULL;
    1.17 +    stringlist_t* _kl = NULL;
    1.18 +    
    1.19 +    sqlite3_reset(session->get_all_keys_for_user);
    1.20 +    sqlite3_bind_text(session->get_all_keys_for_user, 1, user_id, -1, SQLITE_STATIC);
    1.21 +
    1.22 +    int result = -1;
    1.23 +    
    1.24 +    while ((result = sqlite3_step(session->get_all_keys_for_user)) == SQLITE_ROW) {
    1.25 +        const char* keyres = (const char *) sqlite3_column_text(session->get_all_keys_for_user, 0);
    1.26 +        if (keyres) {
    1.27 +            if (_kl)
    1.28 +                stringlist_add(_kl, keyres);
    1.29 +            else
    1.30 +                _kl = new_stringlist(keyres);
    1.31 +        }
    1.32 +    }
    1.33 +    
    1.34 +    if (!_kl)
    1.35 +        return PEP_KEY_NOT_FOUND;
    1.36 +        
    1.37 +    *keys = _kl;
    1.38 +    
    1.39 +    sqlite3_reset(session->get_all_keys_for_user);
    1.40 +
    1.41 +    return status;
    1.42 +}
    1.43 +
    1.44  PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
    1.45                                  char** default_key) {
    1.46      assert(session);
     2.1 --- a/src/keymanagement.h	Wed Aug 22 14:55:43 2018 +0200
     2.2 +++ b/src/keymanagement.h	Mon Aug 27 15:15:59 2018 +0200
     2.3 @@ -358,6 +358,11 @@
     2.4         const char *fpr
     2.5      );
     2.6  
     2.7 +PEP_STATUS get_all_keys_for_user(PEP_SESSION session, 
     2.8 +                                 const char* user_id,
     2.9 +                                 stringlist_t** keys);
    2.10 +
    2.11 +
    2.12  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
    2.13  
    2.14  PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr);
     3.1 --- a/src/message_api.c	Wed Aug 22 14:55:43 2018 +0200
     3.2 +++ b/src/message_api.c	Mon Aug 27 15:15:59 2018 +0200
     3.3 @@ -1580,9 +1580,15 @@
     3.4      
     3.5      if (!session || !revoke_fpr || !new_fpr)
     3.6          return PEP_ILLEGAL_VALUE;
     3.7 -        
     3.8 -    if (!session->sync_session->inject_sync_msg || session->sync_session->sync_management)
     3.9 -        return PEP_SYNC_NO_INJECT_CALLBACK;
    3.10 +
    3.11 +    messageToSend_t send_cb = send_cb = session->messageToSend;
    3.12 +    void* sync_obj = session->sync_obj;
    3.13 +    if (!send_cb) {
    3.14 +        send_cb = session->sync_session->messageToSend;
    3.15 +        sync_obj = session->sync_session->sync_obj;
    3.16 +    }
    3.17 +    if (!send_cb)
    3.18 +        return PEP_SYNC_NO_MESSAGE_SEND_CALLBACK;
    3.19          
    3.20      identity_list* recent_contacts = NULL;
    3.21      message* reset_msg = NULL;
    3.22 @@ -1594,7 +1600,6 @@
    3.23                      
    3.24      identity_list* curr_id_ptr = recent_contacts;
    3.25  
    3.26 -    
    3.27      while (curr_id_ptr) {
    3.28          pEp_identity* curr_id = curr_id_ptr->ident;
    3.29          
    3.30 @@ -1629,12 +1634,10 @@
    3.31              goto pep_free;
    3.32          
    3.33          // insert into queue
    3.34 -        int result = session->sync_session->inject_sync_msg(reset_msg, session->sync_session->sync_management);
    3.35 -
    3.36 -        if (result != 0) {
    3.37 -            status = PEP_SYNC_INJECT_FAILED;
    3.38 +        status = send_cb(sync_obj, reset_msg);
    3.39 +
    3.40 +        if (status != PEP_STATUS_OK)
    3.41              goto pep_free;
    3.42 -        }    
    3.43              
    3.44          // Put into notified DB
    3.45          status = set_reset_contact_notified(session, revoke_fpr, user_id);
    3.46 @@ -3294,7 +3297,7 @@
    3.47          goto pep_free;
    3.48      }
    3.49  
    3.50 -    // Before we go further, let's be sure this was signed be the revoked fpr.
    3.51 +    // Before we go further, let's be sure this was signed by the revoked fpr.
    3.52      if (strcasecmp(revoke_fpr, signing_fpr) != 0) {
    3.53          status = PEP_ILLEGAL_VALUE;
    3.54          goto pep_free;
    3.55 @@ -3329,8 +3332,7 @@
    3.56      }
    3.57          
    3.58      // We know that the signer has the sender's user_id, and that the revoked fpr
    3.59 -    // is theirs. We now need to make sure that we've imported the key we need.
    3.60 -    
    3.61 +    // is theirs. We now need to make sure that we've imported the key we need.    
    3.62      status = find_keys(session, new_fpr, &keylist);
    3.63      if (status != PEP_STATUS_OK)
    3.64          goto pep_free;
    3.65 @@ -3345,6 +3347,7 @@
    3.66      
    3.67      sender_id->comm_type = sender_id->comm_type & (~PEP_ct_confirmed);
    3.68      status = set_identity(session, sender_id);
    3.69 +
    3.70      
    3.71      if (status == PEP_STATUS_OK)
    3.72          status = PEP_KEY_RESET_SUCCESSFUL;
    3.73 @@ -3942,6 +3945,143 @@
    3.74      return status;
    3.75  }
    3.76  
    3.77 +DYNAMIC_API PEP_STATUS key_reset(
    3.78 +        PEP_SESSION session,
    3.79 +        const char* key_id,
    3.80 +        pEp_identity* ident
    3.81 +    )
    3.82 +{
    3.83 +    if (!session)
    3.84 +        return PEP_ILLEGAL_VALUE;
    3.85 +        
    3.86 +    PEP_STATUS status = PEP_STATUS_OK;
    3.87 +        
    3.88 +    char* fpr = NULL;
    3.89 +    char* own_id = NULL;
    3.90 +    identity_list* key_idents = NULL;
    3.91 +    stringlist_t* keys = NULL;
    3.92 +    
    3.93 +    if (key_id) {
    3.94 +        fpr = strdup(key_id);
    3.95 +        if (!fpr)
    3.96 +            return PEP_OUT_OF_MEMORY;
    3.97 +    }
    3.98 +        
    3.99 +    if (!ident) {
   3.100 +        // Get list of own identities
   3.101 +        status = get_default_own_userid(session, &own_id);
   3.102 +        if (status != PEP_STATUS_OK) {
   3.103 +            free(fpr);
   3.104 +            return status;
   3.105 +        }
   3.106 +        if (fpr)
   3.107 +            status = get_identities_by_main_key_id(session, fpr, &key_idents);
   3.108 +        else {
   3.109 +            status = get_all_keys_for_user(session, own_id, &keys);
   3.110 +            if (status == PEP_STATUS_OK) {
   3.111 +                stringlist_t* curr_key;
   3.112 +                for (curr_key = keys; curr_key && curr_key->value; curr_key = curr_key->next) {
   3.113 +                    status = key_reset(session, curr_key->value, NULL);
   3.114 +                    if (status != PEP_STATUS_OK)
   3.115 +                        break;
   3.116 +                }
   3.117 +            }
   3.118 +            goto pep_free;
   3.119 +        }
   3.120 +        
   3.121 +        if (status == PEP_STATUS_OK) {
   3.122 +            // have ident list, or should
   3.123 +            identity_list* curr_ident;
   3.124 +            for (curr_ident = key_idents; curr_ident && curr_ident->ident; 
   3.125 +                 curr_ident = curr_ident->next) {
   3.126 +                pEp_identity* this_identity = curr_ident->ident;
   3.127 +                status = key_reset(session, fpr, this_identity);
   3.128 +                if (status != PEP_STATUS_OK)
   3.129 +                    break;                    
   3.130 +            }
   3.131 +        }
   3.132 +        goto pep_free;
   3.133 +    }
   3.134 +    else {        
   3.135 +        if (is_me(session, ident)) {            
   3.136 +            // FIXME: make sure this IS our fpr?
   3.137 +            if (!fpr) {
   3.138 +                if (ident->fpr)
   3.139 +                    fpr = strdup(ident->fpr);
   3.140 +                else {
   3.141 +                    // Note: this will choke if we've already revoked. Is that
   3.142 +                    // Ok? Or do we need per-identity revokes? Best practice
   3.143 +                    // is to always send in a damned fpr! ;)
   3.144 +                    status = _myself(session, ident, false, true);
   3.145 +                    if (status == PEP_STATUS_OK && ident->fpr) {
   3.146 +                        fpr = strdup(ident->fpr);
   3.147 +                    }
   3.148 +                    else {
   3.149 +                        // last resort?
   3.150 +                        // Get list of own identities
   3.151 +                        char* own_id = NULL;
   3.152 +                        status = get_default_own_userid(session, &own_id);
   3.153 +                        if (status == PEP_STATUS_OK)
   3.154 +                            status = get_user_default_key(session, own_id, &fpr);
   3.155 +                        if (status != PEP_STATUS_OK || !fpr)  {
   3.156 +                            free(own_id);
   3.157 +                            return (status == PEP_STATUS_OK ? PEP_KEY_NOT_FOUND : status);
   3.158 +                        }
   3.159 +                    }
   3.160 +                }
   3.161 +            }
   3.162 +            
   3.163 +            // We now have an fpr. Be careful - it may have been an input fpr, 
   3.164 +            // and it may be connected to the ident    
   3.165 +            char* fpr_backup = ident->fpr;
   3.166 +            ident->fpr = fpr;            
   3.167 +            // Create revocation
   3.168 +            status = revoke_key(session, fpr, NULL);
   3.169 +            // mistrust fpr from trust
   3.170 +            if (status == PEP_STATUS_OK)
   3.171 +                status = key_mistrusted(session, ident);
   3.172 +            // Remove fpr from ALL identities
   3.173 +            // Remove fpr from ALL users    
   3.174 +            if (status == PEP_STATUS_OK)
   3.175 +                status = remove_fpr_as_default(session, ident->fpr);
   3.176 +            if (status == PEP_STATUS_OK)
   3.177 +                status = add_mistrusted_key(session, ident->fpr);
   3.178 +            // generate new key
   3.179 +            if (status == PEP_STATUS_OK)
   3.180 +                status = generate_keypair(session, ident);
   3.181 +            // add to revocation list
   3.182 +            if (status == PEP_STATUS_OK) 
   3.183 +                status = set_revoked(session, fpr, ident->fpr, time(NULL));
   3.184 +            
   3.185 +            // for all active communication partners:
   3.186 +            //      active_send revocation
   3.187 +            if (status == PEP_STATUS_OK)
   3.188 +                status = send_key_reset_to_recents(session, fpr, ident->fpr);
   3.189 +            
   3.190 +            ident->fpr = fpr_backup;
   3.191 +        }
   3.192 +        else { // not is_me
   3.193 +            // remove fpr from all identities
   3.194 +            // remove fpr from all users
   3.195 +            if (status == PEP_STATUS_OK)
   3.196 +                status = remove_fpr_as_default(session, fpr);
   3.197 +            // delete key from key ring
   3.198 +            if (status == PEP_STATUS_OK)
   3.199 +                status = delete_keypair(session, fpr);
   3.200 +            // N.B. If this key is being replaced by something else, it
   3.201 +            // is done outside of this function.    
   3.202 +        }
   3.203 +    }
   3.204 +    
   3.205 +pep_free:
   3.206 +    free(fpr);
   3.207 +    free(own_id);
   3.208 +    free_identity_list(key_idents);
   3.209 +    free_stringlist(keys);    
   3.210 +    return status;
   3.211 +}
   3.212 +
   3.213 +
   3.214  // Note: if comm_type_determine is false, it generally means that
   3.215  // we were unable to get key information for anyone in the list,
   3.216  // likely because a key is missing.
     4.1 --- a/src/pEpEngine.c	Wed Aug 22 14:55:43 2018 +0200
     4.2 +++ b/src/pEpEngine.c	Mon Aug 27 15:15:59 2018 +0200
     4.3 @@ -97,6 +97,32 @@
     4.4      "   order by is_own desc, "
     4.5      "   timestamp desc; ";
     4.6  
     4.7 +static const char *sql_get_identities_by_userid =  
     4.8 +    "select address, fpr, username, comm_type, lang,"
     4.9 +    "   identity.flags | pgp_keypair.flags,"
    4.10 +    "   is_own"
    4.11 +    "   from identity"
    4.12 +    "   join person on id = identity.user_id"
    4.13 +    "   join pgp_keypair on fpr = identity.main_key_id"
    4.14 +    "   join trust on id = trust.user_id"
    4.15 +    "       and pgp_keypair_fpr = identity.main_key_id"    
    4.16 +    "   where identity.user_id = ?1" 
    4.17 +    "   order by is_own desc, "
    4.18 +    "   timestamp desc; ";
    4.19 +
    4.20 +static const char *sql_get_identities_by_main_key_id =  
    4.21 +    "select address, user_id, username, comm_type, lang,"
    4.22 +    "   identity.flags | pgp_keypair.flags,"
    4.23 +    "   is_own"
    4.24 +    "   from identity"
    4.25 +    "   join person on id = identity.user_id"
    4.26 +    "   join pgp_keypair on fpr = identity.main_key_id"
    4.27 +    "   join trust on id = trust.user_id"
    4.28 +    "       and pgp_keypair_fpr = identity.main_key_id"    
    4.29 +    "   where main_key_id = ?1" 
    4.30 +    "   order by is_own desc, "
    4.31 +    "   timestamp desc; ";
    4.32 +
    4.33  static const char *sql_get_identity_without_trust_check =  
    4.34      "select identity.main_key_id, username, lang,"
    4.35      "   identity.flags, is_own"
    4.36 @@ -372,6 +398,10 @@
    4.37      "select main_key_id from person" 
    4.38      "   where id = ?1;";
    4.39  
    4.40 +static const char* sql_get_all_keys_for_user =
    4.41 +    "select pgp_keypair_fpr from trust"
    4.42 +    "   where user_id = ?1; ";
    4.43 +
    4.44  static const char* sql_get_default_own_userid =
    4.45      "select id from person"
    4.46      "   join identity on id = identity.user_id"
    4.47 @@ -1141,10 +1171,24 @@
    4.48              &_session->get_identities_by_address, NULL);
    4.49      assert(int_result == SQLITE_OK);
    4.50  
    4.51 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_userid,
    4.52 +            (int)strlen(sql_get_identities_by_userid), 
    4.53 +            &_session->get_identities_by_userid, NULL);
    4.54 +    assert(int_result == SQLITE_OK);
    4.55 +
    4.56 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_main_key_id,
    4.57 +            (int)strlen(sql_get_identities_by_main_key_id), 
    4.58 +            &_session->get_identities_by_main_key_id, NULL);
    4.59 +    assert(int_result == SQLITE_OK);
    4.60 +
    4.61      int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
    4.62              (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
    4.63      assert(int_result == SQLITE_OK);
    4.64  
    4.65 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_all_keys_for_user,
    4.66 +            (int)strlen(sql_get_all_keys_for_user), &_session->get_all_keys_for_user, NULL);
    4.67 +    assert(int_result == SQLITE_OK);
    4.68 +
    4.69      int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
    4.70              (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
    4.71      assert(int_result == SQLITE_OK);
    4.72 @@ -1493,8 +1537,14 @@
    4.73                  sqlite3_finalize(session->get_identity_without_trust_check);
    4.74              if (session->get_identities_by_address)
    4.75                  sqlite3_finalize(session->get_identities_by_address);            
    4.76 +            if (session->get_identities_by_userid)
    4.77 +                sqlite3_finalize(session->get_identities_by_userid);                
    4.78 +            if (session->get_identities_by_main_key_id)
    4.79 +                sqlite3_finalize(session->get_identities_by_main_key_id);                                
    4.80              if (session->get_user_default_key)
    4.81 -                sqlite3_finalize(session->get_user_default_key);    
    4.82 +                sqlite3_finalize(session->get_user_default_key);
    4.83 +            if (session->get_all_keys_for_user)
    4.84 +                sqlite3_finalize(session->get_all_keys_for_user);                        
    4.85              if (session->get_default_own_userid)
    4.86                  sqlite3_finalize(session->get_default_own_userid);
    4.87              if (session->get_userid_alias_default)
    4.88 @@ -2108,6 +2158,149 @@
    4.89      return status;
    4.90  }
    4.91  
    4.92 +PEP_STATUS get_identities_by_userid(
    4.93 +        PEP_SESSION session,
    4.94 +        const char *user_id,
    4.95 +        identity_list **identities
    4.96 +    )
    4.97 +{
    4.98 +    if (!session || !identities || EMPTYSTR(user_id))
    4.99 +        return PEP_ILLEGAL_VALUE;
   4.100 +
   4.101 +    PEP_STATUS status = PEP_STATUS_OK;
   4.102 +    
   4.103 +    pEp_identity* ident = NULL;
   4.104 +
   4.105 +    *identities = new_identity_list(NULL);
   4.106 +
   4.107 +    sqlite3_reset(session->get_identities_by_userid);
   4.108 +    sqlite3_bind_text(session->get_identities_by_userid, 1, user_id, -1, SQLITE_STATIC);
   4.109 +
   4.110 +    int result = -1;
   4.111 +    while ((result = sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
   4.112 +            // "select address, fpr, username, comm_type, lang,"
   4.113 +            // "   identity.flags | pgp_keypair.flags,"
   4.114 +            // "   is_own"
   4.115 +            // "   from identity"
   4.116 +            // "   join person on id = identity.user_id"
   4.117 +            // "   join pgp_keypair on fpr = identity.main_key_id"
   4.118 +            // "   join trust on id = trust.user_id"
   4.119 +            // "       and pgp_keypair_fpr = identity.main_key_id"    
   4.120 +            // "   where identity.user_id = ?1" 
   4.121 +            // "   order by is_own desc, "
   4.122 +            // "   timestamp desc; ";
   4.123 +
   4.124 +        ident = new_identity(
   4.125 +                    (const char *) sqlite3_column_text(session->get_identities_by_userid, 0),
   4.126 +                    (const char *) sqlite3_column_text(session->get_identities_by_userid, 1),                
   4.127 +                    user_id,
   4.128 +                    (const char *) sqlite3_column_text(session->get_identities_by_userid, 2)
   4.129 +                );
   4.130 +                
   4.131 +        assert(ident);
   4.132 +        if (ident == NULL) {
   4.133 +            sqlite3_reset(session->get_identities_by_userid);
   4.134 +            return PEP_OUT_OF_MEMORY;
   4.135 +        }
   4.136 +
   4.137 +        ident->comm_type = (PEP_comm_type)
   4.138 +            sqlite3_column_int(session->get_identities_by_userid, 3);
   4.139 +        const char* const _lang = (const char *)
   4.140 +            sqlite3_column_text(session->get_identities_by_userid, 4);
   4.141 +        if (_lang && _lang[0]) {
   4.142 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   4.143 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   4.144 +            assert(_lang[2] == 0);
   4.145 +            ident->lang[0] = _lang[0];
   4.146 +            ident->lang[1] = _lang[1];
   4.147 +            ident->lang[2] = 0;
   4.148 +        }
   4.149 +        ident->flags = (unsigned int)
   4.150 +            sqlite3_column_int(session->get_identities_by_userid, 5);
   4.151 +        ident->me = (unsigned int)
   4.152 +            sqlite3_column_int(session->get_identities_by_userid, 6);
   4.153 +    
   4.154 +        identity_list_add(*identities, ident);
   4.155 +        ident = NULL;
   4.156 +    }
   4.157 +
   4.158 +    if ((*identities)->ident == NULL) {
   4.159 +        free_identity_list(*identities);
   4.160 +        *identities = NULL;
   4.161 +        status = PEP_CANNOT_FIND_IDENTITY;
   4.162 +    }
   4.163 +            
   4.164 +    sqlite3_reset(session->get_identities_by_userid);
   4.165 +
   4.166 +    return status;
   4.167 +}
   4.168 +
   4.169 +PEP_STATUS get_identities_by_main_key_id(
   4.170 +        PEP_SESSION session,
   4.171 +        const char *fpr,
   4.172 +        identity_list **identities
   4.173 +    )
   4.174 +{
   4.175 +    if (!session || !identities || EMPTYSTR(fpr))
   4.176 +        return PEP_ILLEGAL_VALUE;
   4.177 +
   4.178 +    PEP_STATUS status = PEP_STATUS_OK;
   4.179 +    
   4.180 +    pEp_identity* ident = NULL;
   4.181 +
   4.182 +    *identities = new_identity_list(NULL);
   4.183 +
   4.184 +    sqlite3_reset(session->get_identities_by_main_key_id);
   4.185 +    sqlite3_bind_text(session->get_identities_by_main_key_id, 1, fpr, -1, SQLITE_STATIC);
   4.186 +
   4.187 +    int result = -1;
   4.188 +    
   4.189 +    while ((result = sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
   4.190 +        ident = new_identity(
   4.191 +                    (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 0),
   4.192 +                    fpr,
   4.193 +                    (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 1),                
   4.194 +                    (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 2)
   4.195 +                );
   4.196 +                
   4.197 +        assert(ident);
   4.198 +        if (ident == NULL) {
   4.199 +            sqlite3_reset(session->get_identities_by_main_key_id);
   4.200 +            return PEP_OUT_OF_MEMORY;
   4.201 +        }
   4.202 +
   4.203 +        ident->comm_type = (PEP_comm_type)
   4.204 +            sqlite3_column_int(session->get_identities_by_main_key_id, 3);
   4.205 +        const char* const _lang = (const char *)
   4.206 +            sqlite3_column_text(session->get_identities_by_main_key_id, 4);
   4.207 +        if (_lang && _lang[0]) {
   4.208 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   4.209 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   4.210 +            assert(_lang[2] == 0);
   4.211 +            ident->lang[0] = _lang[0];
   4.212 +            ident->lang[1] = _lang[1];
   4.213 +            ident->lang[2] = 0;
   4.214 +        }
   4.215 +        ident->flags = (unsigned int)
   4.216 +            sqlite3_column_int(session->get_identities_by_main_key_id, 5);
   4.217 +        ident->me = (unsigned int)
   4.218 +            sqlite3_column_int(session->get_identities_by_main_key_id, 6);
   4.219 +    
   4.220 +        identity_list_add(*identities, ident);
   4.221 +        ident = NULL;
   4.222 +    }
   4.223 +
   4.224 +    if ((*identities)->ident == NULL) {
   4.225 +        free_identity_list(*identities);
   4.226 +        *identities = NULL;
   4.227 +        status = PEP_CANNOT_FIND_IDENTITY;
   4.228 +    }
   4.229 +            
   4.230 +    sqlite3_reset(session->get_identities_by_main_key_id);
   4.231 +
   4.232 +    return status;
   4.233 +}
   4.234 +
   4.235  PEP_STATUS get_identity_without_trust_check(
   4.236          PEP_SESSION session,
   4.237          const char *address,
     5.1 --- a/src/pEpEngine.h	Wed Aug 22 14:55:43 2018 +0200
     5.2 +++ b/src/pEpEngine.h	Mon Aug 27 15:15:59 2018 +0200
     5.3 @@ -1178,6 +1178,53 @@
     5.4          uint64_t *revocation_date
     5.5      );
     5.6  
     5.7 +// Algorithm:
     5.8 +// 
     5.9 +//     Key Reset trigger; either manually or in another protocol, parameter key (optional)
    5.10 +// 
    5.11 +//     if identity given:
    5.12 +// 
    5.13 +//     key reset for one identity
    5.14 +// 
    5.15 +//     else
    5.16 +// 
    5.17 +//     For identity in own identities
    5.18 +// 
    5.19 +//     key reset for one identitiy
    5.20 +// 
    5.21 +//     Key Reset for identity:
    5.22 +// 
    5.23 +//     if own identity:
    5.24 +// 
    5.25 +//     Create revocation
    5.26 +// 
    5.27 +//     add to revocation list
    5.28 +// 
    5.29 +//     mistrust fpr from trust
    5.30 +// 
    5.31 +//     Remove fpr from ALL identities
    5.32 +// 
    5.33 +//     Remove fpr from ALL users
    5.34 +// 
    5.35 +//     generate new key
    5.36 +// 
    5.37 +//     for all active communication partners:
    5.38 +// 
    5.39 +//     active_send revocation
    5.40 +// 
    5.41 +//     else
    5.42 +// 
    5.43 +//     remove fpr from all identities
    5.44 +// 
    5.45 +//     remove fpr from all users
    5.46 +// 
    5.47 +//     delete key from key ring
    5.48 +DYNAMIC_API PEP_STATUS key_reset(
    5.49 +        PEP_SESSION session,
    5.50 +        const char* fpr,
    5.51 +        pEp_identity* ident
    5.52 +    );
    5.53 +
    5.54  
    5.55  // key_created() - get creation date of a key
    5.56  //
    5.57 @@ -1255,6 +1302,12 @@
    5.58          const char *address,
    5.59          identity_list** id_list
    5.60      );
    5.61 +    
    5.62 +PEP_STATUS get_identities_by_userid(
    5.63 +        PEP_SESSION session,
    5.64 +        const char *user_id,
    5.65 +        identity_list **identities
    5.66 +    );    
    5.67          
    5.68  PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
    5.69                                const char* new_uid);
    5.70 @@ -1315,6 +1368,11 @@
    5.71  
    5.72  PEP_STATUS is_own_key(PEP_SESSION session, const char* fpr, bool* own_key);
    5.73  
    5.74 +PEP_STATUS get_identities_by_main_key_id(
    5.75 +        PEP_SESSION session,
    5.76 +        const char *fpr,
    5.77 +        identity_list **identities);
    5.78 +
    5.79  #ifdef __cplusplus
    5.80  }
    5.81  #endif
     6.1 --- a/src/pEp_internal.h	Wed Aug 22 14:55:43 2018 +0200
     6.2 +++ b/src/pEp_internal.h	Mon Aug 27 15:15:59 2018 +0200
     6.3 @@ -131,6 +131,8 @@
     6.4      sqlite3_stmt *get_identity;
     6.5      sqlite3_stmt *get_identity_without_trust_check;
     6.6      sqlite3_stmt *get_identities_by_address;
     6.7 +    sqlite3_stmt *get_identities_by_userid;
     6.8 +    sqlite3_stmt *get_identities_by_main_key_id;
     6.9      sqlite3_stmt *replace_identities_fpr;
    6.10      sqlite3_stmt *replace_main_user_fpr;
    6.11      sqlite3_stmt *get_main_user_fpr;
    6.12 @@ -175,14 +177,16 @@
    6.13      sqlite3_stmt *blacklist_is_listed;
    6.14      sqlite3_stmt *blacklist_retrieve;
    6.15      
    6.16 -    // Own keys
    6.17 +    // Keys
    6.18      sqlite3_stmt *own_key_is_listed;
    6.19      sqlite3_stmt *own_identities_retrieve;
    6.20      sqlite3_stmt *own_keys_retrieve;
    6.21      sqlite3_stmt *get_user_default_key;
    6.22 +    sqlite3_stmt *get_all_keys_for_user;
    6.23          
    6.24      sqlite3_stmt *get_default_own_userid;
    6.25  
    6.26 +
    6.27  //    sqlite3_stmt *set_own_key;
    6.28  
    6.29      // sequence value
     7.1 --- a/src/pgp_gpg.c	Wed Aug 22 14:55:43 2018 +0200
     7.2 +++ b/src/pgp_gpg.c	Mon Aug 27 15:15:59 2018 +0200
     7.3 @@ -298,8 +298,6 @@
     7.4  
     7.5          gpgme = dlopen(LIBGPGME, RTLD_LAZY);
     7.6          if (gpgme == NULL) {
     7.7 -            // FIXME: Hotfix here?
     7.8 -            
     7.9              status = PEP_INIT_CANNOT_LOAD_GPGME;
    7.10              goto pep_error;
    7.11          }