merged in ENGINE-553 ENGINE-551
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Fri, 17 May 2019 16:33:52 +0200
branchENGINE-551
changeset 3724c878a420db18
parent 3717 70160ef539c2
parent 3723 59c62bbfbd57
child 3726 14f9e0f35945
merged in ENGINE-553
     1.1 --- a/src/message_api.c	Thu May 16 18:03:03 2019 +0200
     1.2 +++ b/src/message_api.c	Fri May 17 16:33:52 2019 +0200
     1.3 @@ -33,58 +33,6 @@
     1.4      return false;
     1.5  }
     1.6  
     1.7 -static bool is_wrapper(message* src)
     1.8 -{
     1.9 -    bool retval = false;
    1.10 -    
    1.11 -    if (src) {
    1.12 -        unsigned char pEpstr[] = PEP_SUBJ_STRING;
    1.13 -        if (is_a_pEpmessage(src) || (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0 ||
    1.14 -            _unsigned_signed_strcmp(pEpstr, src->shortmsg, PEP_SUBJ_BYTELEN) == 0) ||
    1.15 -            (strcmp(src->shortmsg, "p=p") == 0)) {
    1.16 -            char* plaintext = src->longmsg;
    1.17 -            if (plaintext) {
    1.18 -                const char *line_end = strchr(plaintext, '\n');
    1.19 -
    1.20 -                if (line_end != NULL) {
    1.21 -                    size_t n = line_end - plaintext;
    1.22 -                    
    1.23 -                    char* copycat = calloc(n + 1, 1);
    1.24 -                    
    1.25 -                    if (copycat) {
    1.26 -                        strlcpy(copycat, plaintext, n+1);
    1.27 -                        
    1.28 -                        if (strstr(copycat, PEP_MSG_WRAP_KEY) && strstr(copycat, "OUTER"))
    1.29 -                            retval = true;
    1.30 -                        
    1.31 -                        free(copycat);
    1.32 -                    }
    1.33 -                }
    1.34 -            }
    1.35 -        }
    1.36 -    }
    1.37 -    return retval;
    1.38 -}
    1.39 -
    1.40 -
    1.41 -/*
    1.42 - * static stringpair_t* search_optfields(const message* msg, const char* key) {
    1.43 - *     if (msg && key) {
    1.44 - *         stringpair_list_t* opt_fields = msg->opt_fields;
    1.45 - *         
    1.46 - *         const stringpair_list_t* curr;
    1.47 - *         
    1.48 - *         for (curr = opt_fields; curr && curr->value; curr = curr->next) {
    1.49 - *             if (curr->value->key) {
    1.50 - *                 if (strcasecmp(curr->value->key, key) == 0)
    1.51 - *                     return curr->value;
    1.52 - *             }
    1.53 - *         } 
    1.54 - *     }
    1.55 - *     return NULL;
    1.56 - * }
    1.57 - */
    1.58 -
    1.59  static char * keylist_to_string(const stringlist_t *keylist)
    1.60  {
    1.61      if (keylist) {
    1.62 @@ -920,7 +868,7 @@
    1.63          _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    1.64  
    1.65          // 2.1, to replace the above
    1.66 -        add_opt_field(attachment, PEP_MSG_WRAP_KEY, inner_type_string); 
    1.67 +        add_opt_field(attachment, X_PEP_MSG_WRAP_KEY, inner_type_string); 
    1.68      }
    1.69      else if (_envelope) {
    1.70          // 2.1 - how do we peel this particular union when we get there?
    1.71 @@ -1039,7 +987,8 @@
    1.72      const message *src,
    1.73      stringlist_t *keys,
    1.74      message *dst,
    1.75 -    PEP_encrypt_flags_t flags
    1.76 +    PEP_encrypt_flags_t flags,
    1.77 +    message_wrap_type wrap_type
    1.78      )
    1.79  {
    1.80      PEP_STATUS status = PEP_STATUS_OK;
    1.81 @@ -1065,7 +1014,7 @@
    1.82      _src->enc_format = PEP_enc_none;
    1.83      
    1.84      // These vars are here to be clear, and because I don't know how this may change in the near future.
    1.85 -    bool wrapped = is_wrapper(_src);
    1.86 +    bool wrapped = (wrap_type != PEP_message_unwrapped);
    1.87      bool mime_encode = !wrapped;
    1.88      status = _mime_encode_message_internal(_src, true, &mimetext, mime_encode, wrapped);
    1.89      assert(status == PEP_STATUS_OK);
    1.90 @@ -1954,8 +1903,9 @@
    1.91      }
    1.92      else {
    1.93          // FIXME - we need to deal with transport types (via flag)
    1.94 +        message_wrap_type wrap_type = PEP_message_unwrapped;
    1.95          if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    1.96 -            message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
    1.97 +            wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
    1.98              _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
    1.99              if (!_src)
   1.100                  goto pEp_error;
   1.101 @@ -1980,7 +1930,7 @@
   1.102          switch (enc_format) {
   1.103              case PEP_enc_PGP_MIME:
   1.104              case PEP_enc_PEP: // BUG: should be implemented extra
   1.105 -                status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   1.106 +                status = encrypt_PGP_MIME(session, _src, keys, msg, flags, wrap_type);
   1.107                  break;
   1.108  
   1.109              case PEP_enc_inline:
   1.110 @@ -2313,7 +2263,7 @@
   1.111      switch (enc_format) {
   1.112          case PEP_enc_PGP_MIME:
   1.113          case PEP_enc_PEP: // BUG: should be implemented extra
   1.114 -            status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   1.115 +            status = encrypt_PGP_MIME(session, _src, keys, msg, flags, PEP_message_default);
   1.116              if (status == PEP_STATUS_OK || (src->longmsg && strstr(src->longmsg, "INNER")))
   1.117                  _cleanup_src(src, false);
   1.118              break;
   1.119 @@ -3566,8 +3516,13 @@
   1.120          if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   1.121              char* wrap_info = NULL;
   1.122              
   1.123 -            if (!has_inner)
   1.124 +            if (!has_inner) {
   1.125                  status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   1.126 +                if (status == PEP_OUT_OF_MEMORY)
   1.127 +                    goto enomem;                
   1.128 +                if (status != PEP_STATUS_OK)
   1.129 +                    goto pEp_error;
   1.130 +            }        
   1.131  
   1.132  //            bool is_transport_wrapper = false;
   1.133              
   1.134 @@ -3636,7 +3591,6 @@
   1.135                          inner_message->enc_format = src->enc_format;
   1.136  
   1.137                          const stringpair_list_t* pEp_protocol_version = NULL;
   1.138 -                        const stringpair_list_t* sender_fpr = NULL;
   1.139                          pEp_protocol_version = stringpair_list_find(inner_message->opt_fields, "X-pEp-Version");
   1.140                          unsigned int pEp_v_major = 0;
   1.141                          unsigned int pEp_v_minor = 0;
   1.142 @@ -3647,80 +3601,91 @@
   1.143                                  pEp_v_minor = 0;
   1.144                              }
   1.145                          }
   1.146 +
   1.147 +                        bool is_inner = false;
   1.148 +                        bool is_key_reset = false;
   1.149 +
   1.150 +                        // Deal with plaintext modification in 1.0 and 2.0 messages
   1.151 +                        status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);   
   1.152 +                        
   1.153 +                        if (status == PEP_OUT_OF_MEMORY)
   1.154 +                            goto enomem;                
   1.155 +                        if (status != PEP_STATUS_OK)
   1.156 +                            goto pEp_error;                                         
   1.157                              
   1.158 -                        if (((pEp_v_major == 2) && (pEp_v_minor > 0)) || (pEp_v_major > 2))                              
   1.159 -                            sender_fpr = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");
   1.160 -
   1.161 -                        // FIXME - Message 2.1                                    
   1.162 -                        status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);                            
   1.163 -                        
   1.164 -                        // ?
   1.165 -                        if (status != PEP_STATUS_OK) {
   1.166 +                        if (((pEp_v_major == 2) && (pEp_v_minor > 0)) || (pEp_v_major > 2)) {
   1.167 +                            stringpair_list_t* searched = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");                             
   1.168 +                            inner_message->_sender_fpr = ((searched && searched->value && searched->value->value) ? strdup(searched->value->value) : NULL);
   1.169 +                            searched = stringpair_list_find(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   1.170 +                            if (searched && searched->value && searched->value->value) {
   1.171 +                                is_inner = (strcmp(searched->value->value, "INNER") == 0);
   1.172 +                                if (!is_inner)
   1.173 +                                    is_key_reset = (strcmp(searched->value->value, "INNER") == 0);
   1.174 +                            }
   1.175 +                        }
   1.176 +                        else {
   1.177 +                                is_inner = (strcmp(wrap_info, "INNER") == 0);
   1.178 +                                if (!is_inner)
   1.179 +                                    is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   1.180 +                        }
   1.181 +                            
   1.182 +
   1.183 +                        if (is_key_reset) {
   1.184 +                            if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   1.185 +                                status = receive_key_reset(session,
   1.186 +                                                           inner_message);
   1.187 +                                if (status != PEP_STATUS_OK) {
   1.188 +                                    free_message(inner_message);
   1.189 +                                    goto pEp_error;
   1.190 +                                }
   1.191 +                                *flags |= PEP_decrypt_flag_consume;
   1.192 +                            }
   1.193 +                        }
   1.194 +                        else if (is_inner) {
   1.195 +
   1.196 +                            // check for private key in decrypted message attachment while importing
   1.197 +                            // N.B. Apparently, we always import private keys into the keyring; however,
   1.198 +                            // we do NOT always allow those to be used for encryption. THAT is controlled
   1.199 +                            // by setting it as an own identity associated with the key in the DB.
   1.200 +                            
   1.201 +                            // If we have a message 2.0 message, we are ONLY going to be ok with keys
   1.202 +                            // we imported from THIS part of the message.
   1.203 +                            imported_private_key_address = false;
   1.204 +                            free(private_il); 
   1.205 +                            private_il = NULL;
   1.206 +                            
   1.207 +                            // import keys from decrypted INNER source
   1.208 +                            status = import_priv_keys_from_decrypted_msg(session, inner_message,
   1.209 +                                                                         &imported_keys,
   1.210 +                                                                         &imported_private_key_address,
   1.211 +                                                                         private_il);
   1.212 +                            if (status != PEP_STATUS_OK)
   1.213 +                                goto pEp_error;            
   1.214 +
   1.215 +                            // THIS is our message
   1.216 +                            // Now, let's make sure we've copied in 
   1.217 +                            // any information sent in by the app if
   1.218 +                            // needed...
   1.219 +                            reconcile_src_and_inner_messages(src, inner_message);
   1.220 +                            
   1.221 +
   1.222 +                            // FIXME: free msg, but check references
   1.223 +                            //src = msg = inner_message;
   1.224 +                            calculated_src = msg = inner_message;
   1.225 +                            
   1.226 +                            // FIXME: should this be msg???
   1.227 +                            if (src->from) {
   1.228 +                                if (!is_me(session, src->from))
   1.229 +                                    update_identity(session, (src->from));
   1.230 +                                else
   1.231 +                                    _myself(session, src->from, false, false, myself_read_only);
   1.232 +                            }
   1.233 +                        }
   1.234 +                        else { // should never happen
   1.235 +                            status = PEP_UNKNOWN_ERROR;
   1.236                              free_message(inner_message);
   1.237                              goto pEp_error;
   1.238                          }
   1.239 -
   1.240 -                        if (wrap_info) {
   1.241 -                            bool is_inner = (strcmp(wrap_info, "INNER") == 0);
   1.242 -                            bool is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   1.243 -
   1.244 -                            if (is_key_reset) {
   1.245 -                                if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   1.246 -                                    status = receive_key_reset(session,
   1.247 -                                                               inner_message);
   1.248 -                                    if (status != PEP_STATUS_OK) {
   1.249 -                                        free_message(inner_message);
   1.250 -                                        goto pEp_error;
   1.251 -                                    }
   1.252 -                                    *flags |= PEP_decrypt_flag_consume;
   1.253 -                                }
   1.254 -                            }
   1.255 -                            else if (is_inner) {
   1.256 -
   1.257 -                                // check for private key in decrypted message attachment while importing
   1.258 -                                // N.B. Apparently, we always import private keys into the keyring; however,
   1.259 -                                // we do NOT always allow those to be used for encryption. THAT is controlled
   1.260 -                                // by setting it as an own identity associated with the key in the DB.
   1.261 -                                
   1.262 -                                // If we have a message 2.0 message, we are ONLY going to be ok with keys
   1.263 -                                // we imported from THIS part of the message.
   1.264 -                                imported_private_key_address = false;
   1.265 -                                free(private_il); 
   1.266 -                                private_il = NULL;
   1.267 -                                
   1.268 -                                // import keys from decrypted INNER source
   1.269 -                                status = import_priv_keys_from_decrypted_msg(session, inner_message,
   1.270 -                                                                             &imported_keys,
   1.271 -                                                                             &imported_private_key_address,
   1.272 -                                                                             private_il);
   1.273 -                                if (status != PEP_STATUS_OK)
   1.274 -                                    goto pEp_error;            
   1.275 -
   1.276 -                                // THIS is our message
   1.277 -                                // Now, let's make sure we've copied in 
   1.278 -                                // any information sent in by the app if
   1.279 -                                // needed...
   1.280 -                                reconcile_src_and_inner_messages(src, inner_message);
   1.281 -                                
   1.282 -
   1.283 -                                // FIXME: free msg, but check references
   1.284 -                                //src = msg = inner_message;
   1.285 -                                calculated_src = msg = inner_message;
   1.286 -                                
   1.287 -                                // FIXME: should this be msg???
   1.288 -                                if (src->from) {
   1.289 -                                    if (!is_me(session, src->from))
   1.290 -                                        update_identity(session, (src->from));
   1.291 -                                    else
   1.292 -                                        _myself(session, src->from, false, false, myself_read_only);
   1.293 -                                }
   1.294 -                            }
   1.295 -                            else { // should never happen
   1.296 -                                status = PEP_UNKNOWN_ERROR;
   1.297 -                                free_message(inner_message);
   1.298 -                                goto pEp_error;
   1.299 -                            }
   1.300 -                        }
   1.301                          inner_message->enc_format = PEP_enc_none;
   1.302                      }
   1.303                      else { // forwarded message, leave it alone
     2.1 --- a/src/message_api.h	Thu May 16 18:03:03 2019 +0200
     2.2 +++ b/src/message_api.h	Fri May 17 16:33:52 2019 +0200
     2.3 @@ -49,6 +49,7 @@
     2.4  typedef unsigned int PEP_encrypt_flags_t;
     2.5  
     2.6  typedef enum _message_wrap_type {
     2.7 +    PEP_message_unwrapped,  // 1.0 or anything we don't wrap    
     2.8      PEP_message_default,    // typical inner/outer message 2.0
     2.9      PEP_message_transport,  // e.g. for onion layers
    2.10      PEP_message_key_reset   // for wrapped key reset information
     3.1 --- a/src/pEp_internal.h	Thu May 16 18:03:03 2019 +0200
     3.2 +++ b/src/pEp_internal.h	Fri May 17 16:33:52 2019 +0200
     3.3 @@ -51,7 +51,14 @@
     3.4  #define PEP_MSG_WRAP_KEY_LEN 26
     3.5  #endif
     3.6  
     3.7 +#ifndef X_PEP_MSG_WRAP_KEY
     3.8 +#define X_PEP_MSG_WRAP_KEY "X-pEp-Wrapped-Message-Info"
     3.9 +#endif
    3.10  
    3.11 +#ifndef X_PEP_SNDR_FPR_KEY
    3.12 +#define X_PEP_SNDR_FPR_KEY "X-pEp-Sender-FPR"
    3.13 +#endif
    3.14 + 
    3.15  #include "platform.h"
    3.16  
    3.17  #ifdef WIN32
     4.1 --- a/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Thu May 16 18:03:03 2019 +0200
     4.2 +++ b/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Fri May 17 16:33:52 2019 +0200
     4.3 @@ -173,9 +173,8 @@
     4.4      
     4.5      int i = 0;
     4.6      
     4.7 -    if (keys->next)
     4.8 -    dedup_stringlist(keys->next);
     4.9 -;
    4.10 +    if (keys && keys->next)
    4.11 +        dedup_stringlist(keys->next);
    4.12      
    4.13      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
    4.14      {
     5.1 --- a/test/src/engine_tests/SenderFPRTests.cc	Thu May 16 18:03:03 2019 +0200
     5.2 +++ b/test/src/engine_tests/SenderFPRTests.cc	Fri May 17 16:33:52 2019 +0200
     5.3 @@ -66,7 +66,7 @@
     5.4      PEP_rating rating;
     5.5      PEP_decrypt_flags_t flags = 0;
     5.6      status = decrypt_message(session, enc_msg, &dec_msg, &keylist, &rating, &flags);
     5.7 -    TEST_ASSERT(status == PEP_STATUS_OK);
     5.8 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
     5.9  
    5.10      char* text = NULL;
    5.11      mime_encode_message(dec_msg, false, &text);