shelving to debug other things ENGINE-398
authorKrista Bennett <krista@pep-project.org>
Fri, 15 Jun 2018 20:17:49 +0200
branchENGINE-398
changeset 2752713b65791080
parent 2747 f1158ffe70e2
child 2799 913e407519e2
shelving to debug other things
src/message_api.c
src/message_api.h
src/pEpEngine.c
src/pEp_internal.h
     1.1 --- a/src/message_api.c	Wed Jun 13 10:32:39 2018 +0200
     1.2 +++ b/src/message_api.c	Fri Jun 15 20:17:49 2018 +0200
     1.3 @@ -857,7 +857,7 @@
     1.4  }
     1.5  
     1.6  static message* wrap_message_as_attachment(message* envelope, 
     1.7 -    message* attachment, bool keep_orig_subject) {
     1.8 +    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
     1.9      
    1.10      if (!attachment)
    1.11          return NULL;
    1.12 @@ -868,14 +868,22 @@
    1.13  
    1.14      replace_opt_field(attachment, "X-pEp-Version", PEP_VERSION);
    1.15          
    1.16 -    if (!_envelope) {
    1.17 +    if (!_envelope && (wrap_type != PEP_message_transport)) {
    1.18          _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
    1.19          status = generate_message_id(_envelope);
    1.20          
    1.21          if (status != PEP_STATUS_OK)
    1.22              goto enomem;
    1.23          
    1.24 -        attachment->longmsg = encapsulate_message_wrap_info("INNER", attachment->longmsg);
    1.25 +        const char* inner_type_string = "";
    1.26 +        switch (wrap_type) {
    1.27 +            case PEP_message_key_reset:
    1.28 +                inner_type_string = "KEY_RESET";
    1.29 +                break;
    1.30 +            default:
    1.31 +                inner_type_string = "INNER";
    1.32 +        }
    1.33 +        attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
    1.34          _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    1.35      }
    1.36      else {
    1.37 @@ -1457,6 +1465,48 @@
    1.38      free(revoked_fpr);
    1.39  }
    1.40  
    1.41 +PEP_STATUS create_standalone_key_reset_message(message** dst, 
    1.42 +                                               pEp_identity* recip,
    1.43 +                                               const char* revoke_fpr,
    1.44 +                                               const char* new_fpr) {
    1.45 +                                                   
    1.46 +    if (!dst || !recip->user_id || !recip->address)
    1.47 +        return PEP_ILLEGAL_VALUE;
    1.48 +
    1.49 +    *dst = NULL;
    1.50 +    // Get own identity user has corresponded with
    1.51 +    pEp_identity* own_identity = NULL;
    1.52 +    PEP_STATUS status = get_own_address_for_contact_id(PEP_SESSION session,
    1.53 +                                                       recip,
    1.54 +                                                       &own_identity);                                                       
    1.55 +    if (status != PEP_STATUS_OK)
    1.56 +        return status;
    1.57 +        
    1.58 +    message* reset_message = new_message(PEP_dir_outgoing);
    1.59 +    reset_message->from = own_identity;
    1.60 +    reset_message->to = new_identity_list(identity_dup(recip)); // ?
    1.61 +    
    1.62 +    status = _attach_key(session, revoke_fpr, reset_message);
    1.63 +    if (status != PEP_STATUS_OK)
    1.64 +        goto pep_free;
    1.65 +    status = _attach_key(session, new_fpr, reset_message);
    1.66 +    if (status != PEP_STATUS_OK)
    1.67 +        goto pep_free;
    1.68 +    
    1.69 +    message* output_msg = NULL;
    1.70 +    
    1.71 +    status = encrypt_message(session, reset_message, NULL,
    1.72 +                             output_msg, PEP_enc_PGP_MIME,
    1.73 +                             PEP_encrypt_flag_key_reset_only);
    1.74 +
    1.75 +    if (status == PEP_STATUS_OK)
    1.76 +        *dst = output_msg;
    1.77 +        
    1.78 +pep_free:
    1.79 +    free_message(reset_message);
    1.80 +    return status;
    1.81 +}
    1.82 +
    1.83  PEP_cryptotech determine_encryption_format(message *msg)
    1.84  {
    1.85      assert(msg);
    1.86 @@ -1580,7 +1630,6 @@
    1.87  
    1.88      identity_list * _il;
    1.89  
    1.90 -
    1.91      if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
    1.92      {
    1.93          // BCC limited support:
    1.94 @@ -1764,7 +1813,8 @@
    1.95      else {
    1.96          // FIXME - we need to deal with transport types (via flag)
    1.97          if ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp) {
    1.98 -            _src = wrap_message_as_attachment(NULL, src, false);
    1.99 +            message_wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   1.100 +            _src = wrap_message_as_attachment(NULL, src, message_wrap_type, false);
   1.101              if (!_src)
   1.102                  goto pep_error;
   1.103          }
   1.104 @@ -2061,8 +2111,8 @@
   1.105      determine_encryption_format(src);
   1.106      if (src->enc_format != PEP_enc_none)
   1.107          return PEP_ILLEGAL_VALUE;
   1.108 -
   1.109      if (target_id && (!target_id->user_id || target_id->user_id[0] == '\0')) {
   1.110 +        
   1.111          char* own_id = NULL;
   1.112          status = get_default_own_userid(session, &own_id);
   1.113          if (own_id) {
   1.114 @@ -2105,7 +2155,7 @@
   1.115      // if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.116      //     _attach_key(session, target_fpr, src);
   1.117  
   1.118 -    _src = wrap_message_as_attachment(NULL, src, false);
   1.119 +    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
   1.120      if (!_src)
   1.121          goto pep_error;
   1.122  
   1.123 @@ -2977,6 +3027,22 @@
   1.124      return NULL;
   1.125  }
   1.126  
   1.127 +PEP_STATUS check_for_own_revoked_key(
   1.128 +        PEP_SESSION session, 
   1.129 +        stringlist_t* keylist,
   1.130 +        char** bad_fpr,
   1.131 +        char** replacement_fpr
   1.132 +    ) 
   1.133 +{
   1.134 +    if (!session || !bad_fpr || !replacement_fpr)
   1.135 +        return PEP_ILLEGAL_VALUE;
   1.136 +    stringlist_t* _k = keylist;
   1.137 +    while (_k) {
   1.138 +        
   1.139 +    }
   1.140 +}
   1.141 +
   1.142 +
   1.143  DYNAMIC_API PEP_STATUS _decrypt_message(
   1.144          PEP_SESSION session,
   1.145          message *src,
   1.146 @@ -3367,6 +3433,10 @@
   1.147          }
   1.148      } // End prepare output message for return
   1.149  
   1.150 +    // 3. Check to see if the sender used a bad key
   1.151 +    char* bad_fpr = NULL;
   1.152 +    status = check_for_own_revoked_key(session, _keylist, &bad_fpr);
   1.153 +    
   1.154      *dst = msg;
   1.155      *keylist = _keylist;
   1.156  
     2.1 --- a/src/message_api.h	Wed Jun 13 10:32:39 2018 +0200
     2.2 +++ b/src/message_api.h	Fri Jun 15 20:17:49 2018 +0200
     2.3 @@ -37,12 +37,19 @@
     2.4      
     2.5      // This is used for outer messages (used to wrap the real message)
     2.6      // This is only used internally and (eventually) by transport functions
     2.7 -    PEP_encrypt_flag_inner_message = 0x8
     2.8 +    PEP_encrypt_flag_inner_message = 0x8,
     2.9 +    
    2.10 +    PEP_encrypt_flag_key_reset_only = 0x16,
    2.11      
    2.12  } PEP_encrypt_flags; 
    2.13  
    2.14  typedef unsigned int PEP_encrypt_flags_t;
    2.15  
    2.16 +typedef enum _message_wrap_type {
    2.17 +    PEP_message_default,    // typical inner/outer message 2.0
    2.18 +    PEP_message_transport,  // e.g. for onion layers
    2.19 +    PEP_message_key_reset   // for wrapped key reset information
    2.20 +} message_wrap_type;
    2.21  
    2.22  // encrypt_message() - encrypt message in memory
    2.23  //
     3.1 --- a/src/pEpEngine.c	Wed Jun 13 10:32:39 2018 +0200
     3.2 +++ b/src/pEpEngine.c	Fri Jun 15 20:17:49 2018 +0200
     3.3 @@ -408,6 +408,10 @@
     3.4      "select revoked_fpr, revocation_date from revoked_keys"
     3.5      "    where replacement_fpr = upper(replace(?1,' ','')) ;";
     3.6  
     3.7 +static const char *sql_get_replacement_fpr = 
     3.8 +    "select replacement_fpr, revocation_date from revoked_keys"
     3.9 +    "    where revoked_fpr = upper(replace(?1,' ','')) ;";
    3.10 +
    3.11  static const char *sql_get_userid_alias_default =
    3.12      "select default_id from alternate_user_id "
    3.13      "   where alternate_id = ?1 ; ";
    3.14 @@ -428,8 +432,20 @@
    3.15      "values (?2, ?1) ;";
    3.16  
    3.17  static const char *sql_add_into_social_graph =
    3.18 -    "insert or replace into social_graph(own_userid, own_address, contact_userid text) "
    3.19 +    "insert or replace into social_graph(own_userid, own_address, contact_userid) "
    3.20      "values (?1, ?2, ?3) ;";
    3.21 +
    3.22 +static const char *sql_get_own_address_binding_from_contact =
    3.23 +    "select own_address from social_graph where own_userid = ?1 and contact_userid = ?2 ;";
    3.24 +
    3.25 +static const char *sql_set_revoke_contact_as_notified =
    3.26 +    "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;";
    3.27 +    
    3.28 +static const char *sql_get_contacted_ids_from_revoke_fpr =
    3.29 +    "select * from revocation_contact_list where fpr = ?1 ;";
    3.30 +
    3.31 +static const char *sql_was_id_for_revoke_contacted = 
    3.32 +    "select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
    3.33      
    3.34  static int user_version(void *_version, int count, char **text, char **name)
    3.35  {
    3.36 @@ -726,13 +742,20 @@
    3.37                  "create table if not exists social_graph (\n"
    3.38                  "    own_userid text,\n"
    3.39                  "    own_address text,\n"
    3.40 -                "    contact_userid text\n"
    3.41 -                "       references person (id)\n"
    3.42 -                "       on delete cascade on update cascade,\n"
    3.43 -                "    CONSTRAINT fk_identity\n"
    3.44 +                "    contact_userid text,\n"
    3.45 +                "    CONSTRAINT fk_own_identity\n"
    3.46                  "       FOREIGN KEY(own_address, own_userid)\n" 
    3.47                  "       REFERENCES identity(address, user_id)\n"
    3.48 -                "       ON DELETE CASCADE ON UPDATE CASCADE\n"
    3.49 +                "       ON DELETE CASCADE ON UPDATE CASCADE,\n"
    3.50 +                ");\n"
    3.51 +                // list of user_ids sent revocation
    3.52 +                "create table if not exists revocation_contact_list (\n"
    3.53 +                "   fpr text not null references pgp_keypair (fpr)\n"
    3.54 +                "       on delete cascade,\n"
    3.55 +                "   contact_id text not null references person (id)\n"
    3.56 +                "       on delete cascade on update cascade,\n"
    3.57 +                "   timestamp integer default (datetime('now')),\n"
    3.58 +                "   PRIMARY KEY(fpr, contact_id)\n"
    3.59                  ");\n"
    3.60                  ,
    3.61              NULL,
    3.62 @@ -1045,13 +1068,19 @@
    3.63                      "create table if not exists social_graph (\n"
    3.64                      "    own_userid text,\n"
    3.65                      "    own_address text,\n"
    3.66 -                    "    contact_userid text\n"
    3.67 -                    "       references person (id)\n"
    3.68 -                    "       on delete cascade on update cascade,\n"
    3.69 -                    "    CONSTRAINT fk_identity\n"
    3.70 +                    "    contact_userid text,\n"
    3.71 +                    "    CONSTRAINT fk_own_identity\n"
    3.72                      "       FOREIGN KEY(own_address, own_userid)\n" 
    3.73                      "       REFERENCES identity(address, user_id)\n"
    3.74 -                    "       ON DELETE CASCADE ON UPDATE CASCADE\n"
    3.75 +                    "       ON DELETE CASCADE ON UPDATE CASCADE,\n"
    3.76 +                    ");\n"
    3.77 +                    "create table if not exists revocation_contact_list (\n"
    3.78 +                    "   fpr text not null references pgp_keypair (fpr)\n"
    3.79 +                    "       on delete cascade,\n"
    3.80 +                    "   contact_id text not null references person (id)\n"
    3.81 +                    "       on delete cascade on update cascade,\n"
    3.82 +                    "   timestamp integer default (datetime('now')),\n"
    3.83 +                    "   PRIMARY KEY(fpr, contact_id)\n"
    3.84                      ");\n"
    3.85                      ,
    3.86                      NULL,
    3.87 @@ -1173,6 +1202,30 @@
    3.88              (int)strlen(sql_add_into_social_graph), &_session->add_into_social_graph, NULL);
    3.89      assert(int_result == SQLITE_OK);
    3.90  
    3.91 +    int_result = sqlite3_prepare_v2(_session->db, 
    3.92 +            sql_get_own_address_binding_from_contact,
    3.93 +            (int)strlen(sql_get_own_address_binding_from_contact), 
    3.94 +            &_session->get_own_address_binding_from_contact, NULL);
    3.95 +    assert(int_result == SQLITE_OK);
    3.96 +
    3.97 +    int_result = sqlite3_prepare_v2(_session->db, 
    3.98 +            sql_set_revoke_contact_as_notified,
    3.99 +            (int)strlen(sql_set_revoke_contact_as_notified), 
   3.100 +            &_session->set_revoke_contact_as_notified, NULL);
   3.101 +    assert(int_result == SQLITE_OK);
   3.102 +
   3.103 +    int_result = sqlite3_prepare_v2(_session->db, 
   3.104 +            sql_get_contacted_ids_from_revoke_fpr,
   3.105 +            (int)strlen(sql_get_contacted_ids_from_revoke_fpr), 
   3.106 +            &_session->get_contacted_ids_from_revoke_fpr, NULL);
   3.107 +    assert(int_result == SQLITE_OK);
   3.108 +
   3.109 +    int_result = sqlite3_prepare_v2(_session->db, 
   3.110 +            sql_get_own_address_binding_from_contact,
   3.111 +            (int)strlen(sql_get_own_address_binding_from_contact), 
   3.112 +            &_session->get_own_address_binding_from_contact, NULL);
   3.113 +    assert(int_result == SQLITE_OK);
   3.114 +
   3.115      int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
   3.116              (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
   3.117      assert(int_result == SQLITE_OK);
   3.118 @@ -1323,6 +1376,10 @@
   3.119              (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
   3.120      assert(int_result == SQLITE_OK);
   3.121      
   3.122 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_replacement_fpr,
   3.123 +            (int)strlen(sql_get_replacement_fpr), &_session->get_replacement_fpr, NULL);
   3.124 +    assert(int_result == SQLITE_OK);
   3.125 +
   3.126      int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
   3.127              (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
   3.128      assert(int_result == SQLITE_OK);
   3.129 @@ -1440,7 +1497,15 @@
   3.130              if (session->exists_person)
   3.131                  sqlite3_finalize(session->exists_person);
   3.132              if (session->add_into_social_graph)
   3.133 -                sqlite3_finalize(session->add_into_social_graph);                        
   3.134 +                sqlite3_finalize(session->add_into_social_graph);  
   3.135 +            if (session->get_own_address_binding_from_contact)
   3.136 +                sqlite3_finalize(session->get_own_address_binding_from_contact);  
   3.137 +            if (session->set_revoke_contact_as_notified)
   3.138 +                sqlite3_finalize(session->set_revoke_contact_as_notified);  
   3.139 +            if (session->get_contacted_ids_from_revoke_fpr)
   3.140 +                sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr);  
   3.141 +            if (session->was_id_for_revoke_contacted)
   3.142 +                sqlite3_finalize(session->was_id_for_revoke_contacted);                                        
   3.143              if (session->set_device_group)
   3.144                  sqlite3_finalize(session->set_device_group);
   3.145              if (session->get_device_group)
   3.146 @@ -1513,7 +1578,8 @@
   3.147                  sqlite3_finalize(session->set_revoked);
   3.148              if (session->get_revoked)
   3.149                  sqlite3_finalize(session->get_revoked);
   3.150 -
   3.151 +            if (session->get_replacement_fpr)
   3.152 +                sqlite3_finalize(session->get_replacement_fpr);                
   3.153              if (session->add_mistrusted_key)
   3.154                  sqlite3_finalize(session->add_mistrusted_key);
   3.155              if (session->delete_mistrusted_key)
   3.156 @@ -2177,9 +2243,9 @@
   3.157      sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
   3.158                        SQLITE_STATIC);
   3.159      sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
   3.160 -                      SQLITE_STATIC);
   3.161                    
   3.162      int result = sqlite3_step(session->exists_identity_entry);
   3.163 +    SQLITE_STATIC);
   3.164      switch (result) {
   3.165          case SQLITE_ROW: {
   3.166              // yeah yeah, I know, we could be lazy here, but it looks bad.
   3.167 @@ -2661,6 +2727,45 @@
   3.168      return PEP_STATUS_OK;
   3.169  }
   3.170  
   3.171 +PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session,
   3.172 +                                          const pEp_identity* contact
   3.173 +                                          pEp_identity** own_ident) {
   3.174 +    if (!contact || !contact->user_id || !own_ident)
   3.175 +        return PEP_ILLEGAL_VALUE;
   3.176 +        
   3.177 +    char* own_user_id = NULL;
   3.178 +    *own_ident = NULL;
   3.179 +    PEP_STATUS status = get_default_own_userid(session, &own_user_id);
   3.180 +    
   3.181 +    if (status != PEP_STATUS_OK)
   3.182 +        return status;
   3.183 +
   3.184 +    sqlite3_reset(session->get_own_address_binding_from_contact);
   3.185 +    sqlite3_bind_text(session->get_own_address_binding_from_contact, 1, own_user_id, -1,
   3.186 +            SQLITE_STATIC);
   3.187 +    sqlite3_bind_text(session->get_own_address_binding_from_contact, 2, contact_ident->user_id, -1,
   3.188 +            SQLITE_STATIC);
   3.189 +
   3.190 +    result = sqlite3_step(session->get_own_address_binding_from_contact);
   3.191 +    switch (result) {
   3.192 +        case SQLITE_ROW:
   3.193 +            const char* const own_address = (const char *)
   3.194 +                sqlite3_column_text(session->get_own_address_binding_from_contact, 0);
   3.195 +            if (own_address) {
   3.196 +                status = get_identity(session, own_address, own_user_id, own_ident);
   3.197 +                if (status == PEP_STATUS_OK) {
   3.198 +                    if (!own_ident)
   3.199 +                        status = PEP_CANNOT_FIND_IDENTITY;
   3.200 +                }
   3.201 +            }
   3.202 +            break;
   3.203 +        default:
   3.204 +            status = PEP_CANNOT_FIND_IDENTITY;
   3.205 +    }
   3.206 +    
   3.207 +    free(own_user_id);
   3.208 +    return status;
   3.209 +}
   3.210  
   3.211  PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
   3.212                                   const char* fpr) 
   3.213 @@ -3915,6 +4020,57 @@
   3.214      return status;
   3.215  }
   3.216  
   3.217 +DYNAMIC_API PEP_STATUS get_replacement_fpr(
   3.218 +        PEP_SESSION session,
   3.219 +        const char *fpr,
   3.220 +        char **revoked_fpr,
   3.221 +        uint64_t *revocation_date
   3.222 +    )
   3.223 +{
   3.224 +    PEP_STATUS status = PEP_STATUS_OK;
   3.225 +
   3.226 +    assert(session &&
   3.227 +           revoked_fpr &&
   3.228 +           fpr && fpr[0]
   3.229 +          );
   3.230 +    
   3.231 +    if (!(session &&
   3.232 +           revoked_fpr &&
   3.233 +           fpr && fpr[0]
   3.234 +          ))
   3.235 +        return PEP_ILLEGAL_VALUE;
   3.236 +
   3.237 +    *revoked_fpr = NULL;
   3.238 +    *revocation_date = 0;
   3.239 +
   3.240 +    sqlite3_reset(session->get_replacement_fpr);
   3.241 +    sqlite3_bind_text(session->get_replacement_fpr, 1, fpr, -1, SQLITE_STATIC);
   3.242 +
   3.243 +    int result;
   3.244 +    
   3.245 +    result = sqlite3_step(session->get_replacement_fpr);
   3.246 +    switch (result) {
   3.247 +        case SQLITE_ROW: {
   3.248 +            *revoked_fpr = strdup((const char *)
   3.249 +                    sqlite3_column_text(session->get_replacement_fpr, 0));
   3.250 +            if(*revoked_fpr)
   3.251 +                *revocation_date = sqlite3_column_int64(session->get_replacement_fpr,
   3.252 +                        1);
   3.253 +            else
   3.254 +                status = PEP_OUT_OF_MEMORY;
   3.255 +
   3.256 +            break;
   3.257 +        }
   3.258 +        default:
   3.259 +            status = PEP_CANNOT_FIND_IDENTITY;
   3.260 +    }
   3.261 +
   3.262 +    sqlite3_reset(session->get_replacement_fpr);
   3.263 +
   3.264 +    return status;
   3.265 +}
   3.266 +
   3.267 +
   3.268  PEP_STATUS key_created(
   3.269          PEP_SESSION session,
   3.270          const char *fpr,
     4.1 --- a/src/pEp_internal.h	Wed Jun 13 10:32:39 2018 +0200
     4.2 +++ b/src/pEp_internal.h	Fri Jun 15 20:17:49 2018 +0200
     4.3 @@ -142,6 +142,10 @@
     4.4      sqlite3_stmt *set_as_pep_user;
     4.5      sqlite3_stmt *is_pep_user;
     4.6      sqlite3_stmt *add_into_social_graph;
     4.7 +    sqlite3_stmt *get_own_address_binding_from_contact;
     4.8 +    sqlite3_stmt *set_revoke_contact_as_notified;
     4.9 +    sqlite3_stmt *get_contacted_ids_from_revoke_fpr;
    4.10 +    sqlite3_stmt *was_id_for_revoke_contacted;
    4.11      sqlite3_stmt *set_device_group;
    4.12      sqlite3_stmt *get_device_group;
    4.13      sqlite3_stmt *set_pgp_keypair;
    4.14 @@ -188,6 +192,7 @@
    4.15      // revoked keys
    4.16      sqlite3_stmt *set_revoked;
    4.17      sqlite3_stmt *get_revoked;
    4.18 +    sqlite3_stmt *get_replacement_fpr;
    4.19  
    4.20      // mistrusted
    4.21      sqlite3_stmt* add_mistrusted_key;