ENGINE-289: shelving to work on another bug ENGINE-289
authorKrista Bennett <krista@pep-project.org>
Wed, 13 Dec 2017 11:42:23 +0100
branchENGINE-289
changeset 2311688b925c3e73
parent 2310 f0aeda5e1ce9
child 2317 b80dd91c8869
ENGINE-289: shelving to work on another bug
src/keymanagement.c
src/pEpEngine.c
src/pEp_internal.h
     1.1 --- a/src/keymanagement.c	Sat Dec 09 13:06:29 2017 +0100
     1.2 +++ b/src/keymanagement.c	Wed Dec 13 11:42:23 2017 +0100
     1.3 @@ -21,6 +21,7 @@
     1.4  
     1.5  #define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
     1.6  
     1.7 +
     1.8  PEP_STATUS elect_pubkey(
     1.9          PEP_SESSION session, pEp_identity * identity
    1.10      )
    1.11 @@ -61,7 +62,6 @@
    1.12              }
    1.13          }
    1.14      }
    1.15 -
    1.16      
    1.17  //    if (_fpr) {
    1.18      free(identity->fpr);
    1.19 @@ -76,6 +76,119 @@
    1.20      return PEP_STATUS_OK;
    1.21  }
    1.22  
    1.23 +static PEP_STATUS validate_fpr(PEP_SESSION session, pEp_identity* ident) {
    1.24 +    
    1.25 +    char* fpr = ident->fpr;
    1.26 +    PEP_comm_type ct = ident->comm_type;
    1.27 +    bool done = false;
    1.28 +    
    1.29 +    bool revoked, expired;
    1.30 +    status = key_revoked(session, fpr, &revoked);    
    1.31 +    
    1.32 +    assert(status == PEP_STATUS_OK);
    1.33 +    if (status != PEP_STATUS_OK) {
    1.34 +         // only happens when there was a problem
    1.35 +         // retrieving key.
    1.36 +         ADD_TO_LOG(status);
    1.37 +     }
    1.38 +    
    1.39 +    status = key_expired(session, identity->fpr, 
    1.40 +                         time(NULL) + (7*24*3600), // In a week
    1.41 +                         &expired);
    1.42 +
    1.43 +    assert(status == PEP_STATUS_OK);
    1.44 +    if (status != PEP_STATUS_OK)
    1.45 +         ADD_TO_LOG(status);
    1.46 +    
    1.47 +    char* retval = fpr;
    1.48 +    
    1.49 +    // FIXME: bits for pEp
    1.50 +    if (ident->me && (ct == PEP_ct_pEp) && !revoked && expired) {
    1.51 +        // extend key
    1.52 +        timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
    1.53 +        status = renew_key(session, fpr, ts);
    1.54 +        free_timestamp(ts);
    1.55 +
    1.56 +        if (status == PEP_STATUS_OK) {
    1.57 +            // if key is valid (second check because pEp key might be extended above)
    1.58 +            //      Return fpr        
    1.59 +            status = key_expired(session, fpr, &expired);            
    1.60 +            // communicate key(?)
    1.61 +            done = true;
    1.62 +        }        
    1.63 +    }
    1.64 +    
    1.65 +    if (revoked)
    1.66 +        ct = PEP_ct_revoked; // not to be stored. To be used here.
    1.67 +    else if (expired)
    1.68 +        ct = PEP_ct_expired;
    1.69 +    
    1.70 +    switch (ct) {
    1.71 +        case PEP_ct_key_expired:
    1.72 +        case PEP_ct_key_revoked
    1.73 +        case PEP_ct_key_b0rken:
    1.74 +            // delete key from being default key for all users/identities
    1.75 +            ident->fpr = NULL;
    1.76 +        default:
    1.77 +            break;
    1.78 +    }            
    1.79 +
    1.80 +    if (!(revoked || expired || !done))
    1.81 +        return PEP_STATUS_OK;
    1.82 +
    1.83 +    return PEP_UNKNOWN_ERROR; // FIXME - better error
    1.84 +}
    1.85 +
    1.86 +// Only call on retrieval of previously stored identity!
    1.87 +// Also, we presume that if the stored_identity was sent in
    1.88 +// without an fpr, there wasn't one in the trust DB for this
    1.89 +// identity.
    1.90 +PEP_STATUS get_valid_pubkey(PEP_STATUS session,
    1.91 +                            PEP_STATUS stored_identity) {
    1.92 +    
    1.93 +    PEP_STATUS status = PEP_STATUS_OK;
    1.94 +
    1.95 +    if (!stored_identity || !stored_identity->user_id)
    1.96 +        return PEP_ILLEGAL_VALUE;
    1.97 +        
    1.98 +    char* stored_fpr = stored_identity->fpr;
    1.99 +    // Input: stored identity retrieved from database
   1.100 +    // if stored identity contains a default key
   1.101 +    if (stored_fpr) {
   1.102 +        status = validate_fpr(session, stored_identity);    
   1.103 +        if (status == PEP_STATUS_OK && stored_identity->fpr)
   1.104 +            return status;
   1.105 +    }
   1.106 +    // if no valid default stored identity key found
   1.107 +    // try to get default key for user_data
   1.108 +    sqlite3_reset(session->get_user_default_key);
   1.109 +    sqlite3_bind_text(session->get_user_default_key, 1, stored_identity->user_id, 
   1.110 +                      -1, SQLITE_STATIC);
   1.111 +    
   1.112 +    const int result = sqlite3_step(session->get_user_default_key);
   1.113 +    const char* user_fpr;
   1.114 +    bool found = false;
   1.115 +    if (result == SQLITE_ROW) {
   1.116 +        user_fpr = 
   1.117 +            (const char *) sqlite3_column_text(session->get_user_default_key, 0);
   1.118 +        if (user_fpr)
   1.119 +            found = true;
   1.120 +    }
   1.121 +    if (!found)
   1.122 +        return NULL;
   1.123 +         
   1.124 +    // There exists a default key for user, so validate
   1.125 +    // FIXME: we have to be able to validate comm_type too.
   1.126 +    retval = validate_fpr(session, user_fpr, WTF,
   1.127 +                          stored_identity->me);
   1.128 +    
   1.129 +    if (!retval) {
   1.130 +        
   1.131 +    }
   1.132 +                          
   1.133 +    return retval;
   1.134 +}
   1.135 +
   1.136  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
   1.137  
   1.138  DYNAMIC_API PEP_STATUS update_identity(
   1.139 @@ -93,12 +206,109 @@
   1.140      if (!(session && identity && !EMPTYSTR(identity->address)))
   1.141          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   1.142  
   1.143 -    // dunno if we should keep this function shortcut.
   1.144 -    if (_identity_me(identity)) {
   1.145 -        identity->me = true;
   1.146 -        return _myself(session, identity, false, true);
   1.147 +    char* own_id = NULL;
   1.148 +    status = get_own_userid(session, &own_id);    
   1.149 +
   1.150 +    // Is this me, temporary or not? If so, _myself() is the right call.
   1.151 +    if (identity->me || 
   1.152 +       (own_id && identity->user_id && (strcmp(own_id, identity->user_id) == 0))) 
   1.153 +    {
   1.154 +        status = _myself(session, identity, false, true);
   1.155 +        free(own_id);
   1.156 +        return status;
   1.157      }
   1.158  
   1.159 +    // We have, at least, an address.
   1.160 +    // Retrieve stored identity information!    
   1.161 +    pEp_identity* stored_ident = NULL;
   1.162 +    if (identity->user_id) {            
   1.163 +        // (we're gonna update the trust/fpr anyway, so we user the no-fpr variant)
   1.164 +        //      * do get_identity() to retrieve stored identity information
   1.165 +        status = get_identity_without_fpr(session, &stored_ident);
   1.166 +        
   1.167 +        if (identity->username) {
   1.168 +            /*
   1.169 +             * Retrieving information of an identity with username supplied
   1.170 +             *      Input: user_id, address, username
   1.171 +             */
   1.172 +            if (status == PEP_STATUS_OK && stored_ident) { 
   1.173 +                //  * if identity available
   1.174 +                //      * patch it with username
   1.175 +                //          (note: this will happen when 
   1.176 +                //           setting automatically below...)
   1.177 +                //      * elect valid key for identity (see below)
   1.178 +                //    * if valid key exists
   1.179 +                //        * set identity comm_type from trust db (user_id, FPR)
   1.180 +                //        * set return value's fpr
   1.181 +                //    * call set_identity() to store
   1.182 +                status = set_identity(identity);
   1.183 +            //  * else (identity unavailable)
   1.184 +            //      * create identity with user_id, address, username
   1.185 +            //    * search for a temporary identity for address and username
   1.186 +            //    * if temporary identity available
   1.187 +            //      * modify identity with username
   1.188 +            //    * else
   1.189 +            //    * call set_identity() to store
   1.190 +            //  * Return: modified or created identity
   1.191 +             // 
   1.192 +        }
   1.193 +        else {
   1.194 +            /*
   1.195 +             * Retrieving information of an identity without username supplied
   1.196 +             *      Input: user_id, address
   1.197 +             */
   1.198 +            //    * doing get_identity() to retrieve stored identity information
   1.199 +            //    * if identity not available
   1.200 +            //      * return error status (identity not found)
   1.201 +            //    * else
   1.202 +            //      * elect valid key for identity (see below)
   1.203 +            //      * if valid key exists
   1.204 +            //        * set identity comm_type from trust db (user_id, FPR)
   1.205 +            //        * set return value's fpr
   1.206 +            //        * ...? (do we also set the stored fpr?)
   1.207 +            //      * Return: identity if available
   1.208 +
   1.209 +            
   1.210 +        }
   1.211 +    }
   1.212 +    else if (identity->username) {
   1.213 +        /*
   1.214 +         * Temporary identity information with username supplied
   1.215 +            * Input: address, username (no others)
   1.216 +         */
   1.217 +         
   1.218 +        //  * Search for an identity with non-temporary user_id with that mapping
   1.219 +        //  * if one found
   1.220 +        //    * find valid key for identity (see below)
   1.221 +        //    * if valid key exists
   1.222 +        //      * set identity comm_type from trust db (user_id, FPR)
   1.223 +        //      * set return value's fpr
   1.224 +        //      * ...? (do we also set the stored fpr?)
   1.225 +        //    * Return this identity
   1.226 +        //  * if many found
   1.227 +        //    * Return the one with newest modification date (yes, this is a heuristics)
   1.228 +        //  * else
   1.229 +        //    * create temporary identity, store it, and Return this
   1.230 +    }
   1.231 +    else {
   1.232 +        /*
   1.233 +         * Temporary identity information without username suplied
   1.234 +            * Input: address (no others)
   1.235 +         */
   1.236 +         
   1.237 +        //    * Search for identity with this address
   1.238 +        //    * If exactly one found
   1.239 +        //      * elect valid key for identity (see below)
   1.240 +        //      * if valid key exists
   1.241 +        //        * set identity comm_type from trust db (user_id, FPR)
   1.242 +        //        * set return value's fpr
   1.243 +        //        * ...? (do we also set the stored fpr?)
   1.244 +        //      * Return this identity
   1.245 +        //    * else
   1.246 +        //      * return error status (too little information)
   1.247 +    }
   1.248 +
   1.249 +
   1.250      int _no_user_id = EMPTYSTR(identity->user_id);
   1.251      int _did_elect_new_key = 0;
   1.252  
     2.1 --- a/src/pEpEngine.c	Sat Dec 09 13:06:29 2017 +0100
     2.2 +++ b/src/pEpEngine.c	Wed Dec 13 11:42:23 2017 +0100
     2.3 @@ -210,6 +210,10 @@
     2.4      "   join identity on trust.user_id = identity.user_id"
     2.5      "   where identity.is_own = 1";
     2.6  
     2.7 +static const char* sql_get_user_default_key =
     2.8 +    "select main_key_id from person" 
     2.9 +    "   where id = ?1;";
    2.10 +
    2.11  static const char* sql_get_own_userid =
    2.12      "select id from person"
    2.13      "   join identity on id = identity.user_id"
    2.14 @@ -708,6 +712,10 @@
    2.15              &_session->get_identity_without_fpr, NULL);
    2.16      assert(int_result == SQLITE_OK);
    2.17  
    2.18 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
    2.19 +            (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
    2.20 +    assert(int_result == SQLITE_OK);
    2.21 +
    2.22      int_result = sqlite3_prepare_v2(_session->db, sql_get_own_userid,
    2.23              (int)strlen(sql_get_own_userid), &_session->get_own_userid, NULL);
    2.24      assert(int_result == SQLITE_OK);
    2.25 @@ -955,6 +963,8 @@
    2.26                  sqlite3_finalize(session->get_identity);
    2.27              if (session->get_identity_without_fpr)
    2.28                  sqlite3_finalize(session->get_identity_without_fpr);    
    2.29 +            if (session->get_user_default_key)
    2.30 +                sqlite3_finalize(session->get_user_default_key);    
    2.31              if (session->get_own_userid)
    2.32                  sqlite3_finalize(session->get_own_userid);
    2.33              if (session->replace_identities_fpr)
     3.1 --- a/src/pEp_internal.h	Sat Dec 09 13:06:29 2017 +0100
     3.2 +++ b/src/pEp_internal.h	Wed Dec 13 11:42:23 2017 +0100
     3.3 @@ -124,7 +124,6 @@
     3.4      sqlite3_stmt *log;
     3.5      sqlite3_stmt *trustword;
     3.6      sqlite3_stmt *get_identity;
     3.7 -    sqlite3_stmt *get_identity_without_fpr;    
     3.8      sqlite3_stmt *replace_identities_fpr;
     3.9      sqlite3_stmt *set_person;
    3.10      sqlite3_stmt *set_device_group;
    3.11 @@ -153,6 +152,8 @@
    3.12      sqlite3_stmt *own_key_is_listed;
    3.13      sqlite3_stmt *own_identities_retrieve;
    3.14      sqlite3_stmt *own_keys_retrieve;
    3.15 +    sqlite3_stmt *get_user_default_key;
    3.16 +        
    3.17      sqlite3_stmt *get_own_userid;
    3.18  
    3.19  //    sqlite3_stmt *set_own_key;
    3.20 @@ -343,13 +344,6 @@
    3.21      return comparison == 0;
    3.22  }
    3.23  
    3.24 -static inline bool _identity_me(
    3.25 -        pEp_identity * identity
    3.26 -    )
    3.27 -{
    3.28 -    return identity->me || (identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0);
    3.29 -}
    3.30 -
    3.31  // size is the length of the bytestr that's coming in. This is really only intended
    3.32  // for comparing two full strings. If charstr's length is different from bytestr_size,
    3.33  // we'll return a non-zero value.