A whole horde of trust fixes (mistrust list added, tests fixed, and sneaky null string in elect key removed) mistrust_fixes
authorKrista Bennett <krista@pep-project.org>
Sun, 04 Feb 2018 03:36:08 +0100
branchmistrust_fixes
changeset 24714f1c2d62b2dd
parent 2467 ef6bb2e8a84c
child 2472 ebe750121b3d
child 2475 4f96c6ab6156
A whole horde of trust fixes (mistrust list added, tests fixed, and sneaky null string in elect key removed)
src/keymanagement.c
src/keymanagement.h
src/pEpEngine.c
src/pEp_internal.h
test/mistrust_undo_test.cc
test/new_update_id_and_myself_test.cc
     1.1 --- a/src/keymanagement.c	Thu Feb 01 13:57:04 2018 +0100
     1.2 +++ b/src/keymanagement.c	Sun Feb 04 03:36:08 2018 +0100
     1.3 @@ -77,8 +77,11 @@
     1.4                      _comm_type_key > identity->comm_type)
     1.5                  {
     1.6                      bool blacklisted;
     1.7 -                    status = blacklist_is_listed(session, _keylist->value, &blacklisted);
     1.8 -                    if (status == PEP_STATUS_OK && !blacklisted) {
     1.9 +                    bool mistrusted;
    1.10 +                    status = is_mistrusted_key(session, _keylist->value, &mistrusted);
    1.11 +                    if (status == PEP_STATUS_OK)
    1.12 +                        status = blacklist_is_listed(session, _keylist->value, &blacklisted);
    1.13 +                    if (status == PEP_STATUS_OK && !mistrusted && !blacklisted) {
    1.14                          identity->comm_type = _comm_type_key;
    1.15                          _fpr = _keylist->value;
    1.16                      }
    1.17 @@ -88,10 +91,14 @@
    1.18      }
    1.19      free(identity->fpr);
    1.20  
    1.21 -    identity->fpr = strdup(_fpr);
    1.22 -    if (identity->fpr == NULL) {
    1.23 -        free_stringlist(keylist);
    1.24 -        return PEP_OUT_OF_MEMORY;
    1.25 +    if (!_fpr || _fpr[0] == '\0')
    1.26 +        identity->fpr = NULL;
    1.27 +    else {    
    1.28 +        identity->fpr = strdup(_fpr);
    1.29 +        if (identity->fpr == NULL) {
    1.30 +            free_stringlist(keylist);
    1.31 +            return PEP_OUT_OF_MEMORY;
    1.32 +        }
    1.33      }
    1.34      
    1.35      free_stringlist(keylist);
    1.36 @@ -370,14 +377,15 @@
    1.37              stored_ident->comm_type = ct;
    1.38          }
    1.39      }
    1.40 +    else {
    1.41 +        if (stored_ident->comm_type == PEP_ct_unknown)
    1.42 +            stored_ident->comm_type = PEP_ct_key_not_found;
    1.43 +    }
    1.44      free(return_id->fpr);
    1.45      return_id->fpr = NULL;
    1.46      if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
    1.47          return_id->fpr = strdup(stored_ident->fpr);
    1.48          
    1.49 -    // This is outside the if block ON PURPOSE - we return an empty FPR +
    1.50 -    // the reason why a key wasn't used in the comm_type string if we can't
    1.51 -    // find or use one.
    1.52      return_id->comm_type = stored_ident->comm_type;
    1.53                  
    1.54      // We patch the DB with the input username, but if we didn't have
    1.55 @@ -1065,6 +1073,8 @@
    1.56              status = mark_as_compromized(session, ident->fpr);
    1.57          if (status == PEP_STATUS_OK)
    1.58              status = remove_fpr_as_default(session, ident->fpr);
    1.59 +        if (status == PEP_STATUS_OK)
    1.60 +            status = add_mistrusted_key(session, ident->fpr);
    1.61      }
    1.62  
    1.63      return status;
    1.64 @@ -1083,12 +1093,15 @@
    1.65      if (!cached_ident)
    1.66          status = PEP_CANNOT_FIND_IDENTITY;
    1.67      else {
    1.68 -        status = set_identity(session, cached_ident);            
    1.69 -        free_identity(session->cached_mistrusted);
    1.70 +        status = delete_mistrusted_key(session, cached_ident->fpr);
    1.71 +        if (status == PEP_STATUS_OK) {
    1.72 +            status = set_identity(session, cached_ident);            
    1.73 +            free_identity(session->cached_mistrusted);
    1.74 +        }
    1.75      }
    1.76      
    1.77      session->cached_mistrusted = NULL;
    1.78 -
    1.79 +    
    1.80      return status;
    1.81  }
    1.82  
    1.83 @@ -1129,7 +1142,19 @@
    1.84      if (status != PEP_STATUS_OK)
    1.85          goto pep_free;
    1.86  
    1.87 +    bool mistrusted_key = false;
    1.88          
    1.89 +    status = is_mistrusted_key(session, ident->fpr, &mistrusted_key);
    1.90 +
    1.91 +    if (status != PEP_STATUS_OK)
    1.92 +        goto pep_free;
    1.93 +    
    1.94 +    if (mistrusted_key)
    1.95 +        status = delete_mistrusted_key(session, ident->fpr);
    1.96 +
    1.97 +    if (status != PEP_STATUS_OK)
    1.98 +        goto pep_free;
    1.99 +    
   1.100      input_copy->comm_type = new_trust;
   1.101          
   1.102      tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
   1.103 @@ -1569,3 +1594,80 @@
   1.104  
   1.105      return session->cryptotech[PEP_crypt_OpenPGP].contains_priv_key(session, fpr, has_private);
   1.106  }
   1.107 +
   1.108 +PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr)
   1.109 +{
   1.110 +    int result;
   1.111 +
   1.112 +    assert(!EMPTYSTR(fpr));
   1.113 +    
   1.114 +    if (!(session) || EMPTYSTR(fpr))
   1.115 +        return PEP_ILLEGAL_VALUE;
   1.116 +
   1.117 +    sqlite3_reset(session->add_mistrusted_key);
   1.118 +    sqlite3_bind_text(session->add_mistrusted_key, 1, fpr, -1,
   1.119 +            SQLITE_STATIC);
   1.120 +
   1.121 +    result = sqlite3_step(session->add_mistrusted_key);
   1.122 +    sqlite3_reset(session->add_mistrusted_key);
   1.123 +
   1.124 +    if (result != SQLITE_DONE)
   1.125 +        return PEP_CANNOT_SET_PGP_KEYPAIR; // FIXME: Better status?
   1.126 +
   1.127 +    return PEP_STATUS_OK;
   1.128 +}
   1.129 +
   1.130 +PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr)
   1.131 +{
   1.132 +    int result;
   1.133 +
   1.134 +    assert(!EMPTYSTR(fpr));
   1.135 +    
   1.136 +    if (!(session) || EMPTYSTR(fpr))
   1.137 +        return PEP_ILLEGAL_VALUE;
   1.138 +
   1.139 +    sqlite3_reset(session->delete_mistrusted_key);
   1.140 +    sqlite3_bind_text(session->delete_mistrusted_key, 1, fpr, -1,
   1.141 +            SQLITE_STATIC);
   1.142 +
   1.143 +    result = sqlite3_step(session->delete_mistrusted_key);
   1.144 +    sqlite3_reset(session->delete_mistrusted_key);
   1.145 +
   1.146 +    if (result != SQLITE_DONE)
   1.147 +        return PEP_UNKNOWN_ERROR; // FIXME: Better status?
   1.148 +
   1.149 +    return PEP_STATUS_OK;
   1.150 +}
   1.151 +
   1.152 +PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr,
   1.153 +                             bool* mistrusted)
   1.154 +{
   1.155 +    PEP_STATUS status = PEP_STATUS_OK;
   1.156 +
   1.157 +    assert(session);
   1.158 +    assert(!EMPTYSTR(fpr));
   1.159 +
   1.160 +    if (!(session && fpr))
   1.161 +        return PEP_ILLEGAL_VALUE;
   1.162 +
   1.163 +    *mistrusted = false;
   1.164 +
   1.165 +    sqlite3_reset(session->is_mistrusted_key);
   1.166 +    sqlite3_bind_text(session->is_mistrusted_key, 1, fpr, -1, SQLITE_STATIC);
   1.167 +
   1.168 +    int result;
   1.169 +
   1.170 +    result = sqlite3_step(session->is_mistrusted_key);
   1.171 +    switch (result) {
   1.172 +    case SQLITE_ROW:
   1.173 +        *mistrusted = sqlite3_column_int(session->is_mistrusted_key, 0);
   1.174 +        status = PEP_STATUS_OK;
   1.175 +        break;
   1.176 +
   1.177 +    default:
   1.178 +        status = PEP_UNKNOWN_ERROR;
   1.179 +    }
   1.180 +
   1.181 +    sqlite3_reset(session->is_mistrusted_key);
   1.182 +    return status;
   1.183 +}
     2.1 --- a/src/keymanagement.h	Thu Feb 01 13:57:04 2018 +0100
     2.2 +++ b/src/keymanagement.h	Sun Feb 04 03:36:08 2018 +0100
     2.3 @@ -344,6 +344,11 @@
     2.4  
     2.5  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
     2.6  
     2.7 +PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr);
     2.8 +PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr);
     2.9 +PEP_STATUS is_mistrusted_key(PEP_SESSION session, const char* fpr, bool* mistrusted);
    2.10 +
    2.11 +
    2.12  #ifdef __cplusplus
    2.13  }
    2.14  #endif
     3.1 --- a/src/pEpEngine.c	Thu Feb 01 13:57:04 2018 +0100
     3.2 +++ b/src/pEpEngine.c	Sun Feb 04 03:36:08 2018 +0100
     3.3 @@ -294,6 +294,17 @@
     3.4      "select default_id from alternate_user_id "
     3.5      "   where alternate_id = ?1 ; ";
     3.6  
     3.7 +// Revocation tracking
     3.8 +static const char *sql_add_mistrusted_key =
     3.9 +    "insert or replace into mistrusted_keys (fpr) "
    3.10 +    "   values (upper(replace(?1,' ',''))) ;";
    3.11 +        
    3.12 +static const char *sql_delete_mistrusted_key = 
    3.13 +    "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
    3.14 +
    3.15 +static const char *sql_is_mistrusted_key = 
    3.16 +    "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
    3.17 +
    3.18  static const char *sql_add_userid_alias =
    3.19      "insert or replace into alternate_user_id (default_id, alternate_id) "
    3.20      "values (?1, ?2) ;";
    3.21 @@ -781,17 +792,17 @@
    3.22                  );
    3.23                  assert(int_result == SQLITE_OK);    
    3.24              }
    3.25 -        }
    3.26 -        if (version < 7) {
    3.27 -            int_result = sqlite3_exec(
    3.28 -                _session->db,
    3.29 -                "create table if not exists mistrusted_keys (\n"
    3.30 -                "    fpr text primary key\n"
    3.31 -                ");\n"            
    3.32 -                NULL,
    3.33 -                NULL,
    3.34 -                NULL
    3.35 -            );
    3.36 +            if (version < 7) {
    3.37 +                int_result = sqlite3_exec(
    3.38 +                    _session->db,
    3.39 +                    "create table if not exists mistrusted_keys (\n"
    3.40 +                    "    fpr text primary key\n"
    3.41 +                    ");\n",            
    3.42 +                    NULL,
    3.43 +                    NULL,
    3.44 +                    NULL
    3.45 +                );
    3.46 +            }
    3.47          }
    3.48          else { 
    3.49              // Version from DB was 0, it means this is initial setup.
    3.50 @@ -1015,6 +1026,18 @@
    3.51              (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
    3.52      assert(int_result == SQLITE_OK);
    3.53      
    3.54 +    int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
    3.55 +            (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
    3.56 +    assert(int_result == SQLITE_OK);
    3.57 +
    3.58 +    int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
    3.59 +            (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
    3.60 +    assert(int_result == SQLITE_OK);
    3.61 +
    3.62 +    int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
    3.63 +            (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
    3.64 +    assert(int_result == SQLITE_OK);
    3.65 +    
    3.66      status = init_cryptotech(_session, in_first);
    3.67      if (status != PEP_STATUS_OK)
    3.68          goto pep_error;
    3.69 @@ -1174,6 +1197,13 @@
    3.70              if (session->get_revoked)
    3.71                  sqlite3_finalize(session->get_revoked);
    3.72  
    3.73 +            if (session->add_mistrusted_key)
    3.74 +                sqlite3_finalize(session->add_mistrusted_key);
    3.75 +            if (session->delete_mistrusted_key)
    3.76 +                sqlite3_finalize(session->delete_mistrusted_key);
    3.77 +            if (session->is_mistrusted_key)
    3.78 +                sqlite3_finalize(session->is_mistrusted_key);
    3.79 +
    3.80              if (session->db)
    3.81                  sqlite3_close_v2(session->db);
    3.82              if (session->system_db)
     4.1 --- a/src/pEp_internal.h	Thu Feb 01 13:57:04 2018 +0100
     4.2 +++ b/src/pEp_internal.h	Sun Feb 04 03:36:08 2018 +0100
     4.3 @@ -173,6 +173,11 @@
     4.4      sqlite3_stmt *set_revoked;
     4.5      sqlite3_stmt *get_revoked;
     4.6  
     4.7 +    // mistrusted
     4.8 +    sqlite3_stmt* add_mistrusted_key;
     4.9 +    sqlite3_stmt* is_mistrusted_key;    
    4.10 +    sqlite3_stmt* delete_mistrusted_key;
    4.11 +    
    4.12      // aliases
    4.13      sqlite3_stmt *get_userid_alias_default;
    4.14      sqlite3_stmt *add_userid_alias;
     5.1 --- a/test/mistrust_undo_test.cc	Thu Feb 01 13:57:04 2018 +0100
     5.2 +++ b/test/mistrust_undo_test.cc	Sun Feb 04 03:36:08 2018 +0100
     5.3 @@ -58,8 +58,12 @@
     5.4      assert(status == PEP_STATUS_OK);
     5.5      status = update_identity(session,recip1);
     5.6      assert(status == PEP_STATUS_OK);
     5.7 +    assert(recip1->comm_type == PEP_ct_key_not_found);
     5.8 +    recip1->fpr = strdup("BACC7A60A88A39A25D99B4A545D7542F39E5DAB5");
     5.9 +    status = get_trust(session, recip1);
    5.10      assert(recip1->comm_type == PEP_ct_mistrusted);
    5.11 -    cout << "Mistrusted mistrust.undo.test@pep-project.org (BACC7A60A88A39A25D99B4A545D7542F39E5DAB5) and comm_type set to PEP_ct_mistrusted)." << endl  << endl;    
    5.12 +     
    5.13 +    cout << "Mistrusted mistrust.undo.test@pep-project.org (BACC7A60A88A39A25D99B4A545D7542F39E5DAB5) and comm_type IN DB set to PEP_ct_mistrusted)." << endl  << endl;    
    5.14      
    5.15      cout << "Undo mistrust (restore identity and trust in DB)" << endl;
    5.16      // Undo it
     6.1 --- a/test/new_update_id_and_myself_test.cc	Thu Feb 01 13:57:04 2018 +0100
     6.2 +++ b/test/new_update_id_and_myself_test.cc	Sun Feb 04 03:36:08 2018 +0100
     6.3 @@ -601,7 +601,7 @@
     6.4      assert(!revokemaster_3000->fpr);
     6.5      assert(revokemaster_3000->username);
     6.6      assert(strcmp(revokemaster_3000->user_id, revoke_uuid) == 0);
     6.7 -    assert(revokemaster_3000->comm_type == PEP_ct_key_revoked || revokemaster_3000->comm_type == PEP_ct_mistrusted);
     6.8 +    assert(revokemaster_3000->comm_type == PEP_ct_key_not_found);
     6.9      cout << "Success! No key found. The comm_status error was " << revokemaster_3000->comm_type << "and the return status was " << tl_status_string(status) << endl;
    6.10  
    6.11      free_identity(revokemaster_3000);