ENGINE-275: single encryption works, but mime_encode is doing something stupid. finding out what now... ENGINE-275
authorKrista Bennett <krista@pep-project.org>
Wed, 11 Oct 2017 15:35:52 +0200
branchENGINE-275
changeset 2152771f8f862d51
parent 2151 9bc683c97475
child 2153 d0182c01f0eb
ENGINE-275: single encryption works, but mime_encode is doing something stupid. finding out what now...
src/message_api.c
src/pEpEngine.h
test/revoke_regen_attach_test.cc
     1.1 --- a/src/message_api.c	Tue Oct 10 15:03:17 2017 +0200
     1.2 +++ b/src/message_api.c	Wed Oct 11 15:35:52 2017 +0200
     1.3 @@ -134,46 +134,6 @@
     1.4      return ptext;
     1.5  }
     1.6  
     1.7 -
     1.8 -static char * combine_short_and_long(const char *shortmsg, const char *longmsg)
     1.9 -{
    1.10 -    assert(shortmsg);
    1.11 -    
    1.12 -    unsigned char pepstr[] = PEP_SUBJ_STRING;
    1.13 -    assert(strcmp(shortmsg, "pEp") != 0 && _unsigned_signed_strcmp(pepstr, shortmsg, PEP_SUBJ_BYTELEN) != 0); 
    1.14 -    
    1.15 -    if (!shortmsg || strcmp(shortmsg, "pEp") == 0 || 
    1.16 -                     _unsigned_signed_strcmp(pepstr, shortmsg, PEP_SUBJ_BYTELEN) == 0) {
    1.17 -        if (!longmsg) {
    1.18 -            return NULL;
    1.19 -        }
    1.20 -        else {
    1.21 -            char *result = strdup(longmsg);
    1.22 -            assert(result);
    1.23 -            return result;
    1.24 -        }
    1.25 -    }
    1.26 -
    1.27 -    if (longmsg == NULL)
    1.28 -        longmsg = "";
    1.29 -
    1.30 -    const char * const newlines = "\n\n";
    1.31 -    const size_t NL_LEN = 2;
    1.32 -
    1.33 -    const size_t bufsize = PEP_SUBJ_KEY_LEN + strlen(shortmsg) + NL_LEN + strlen(longmsg) + 1;
    1.34 -    char * ptext = calloc(1, bufsize);
    1.35 -    assert(ptext);
    1.36 -    if (ptext == NULL)
    1.37 -        return NULL;
    1.38 -
    1.39 -    strlcpy(ptext, PEP_SUBJ_KEY, bufsize);
    1.40 -    strlcat(ptext, shortmsg, bufsize);
    1.41 -    strlcat(ptext, newlines, bufsize);
    1.42 -    strlcat(ptext, longmsg, bufsize);
    1.43 -
    1.44 -    return ptext;
    1.45 -}
    1.46 -
    1.47  /* 
    1.48     WARNING: For the moment, this only works for the first line of decrypted
    1.49     plaintext because we don't need more. IF WE DO, THIS MUST BE EXPANDED, or
    1.50 @@ -411,9 +371,7 @@
    1.51  
    1.52  static message* extract_minimal_envelope(const message* src, 
    1.53                                           PEP_msg_direction direct) {
    1.54 -                                             
    1.55 -    unsigned char pepstr[] = PEP_SUBJ_STRING;
    1.56 -    
    1.57 +                                                 
    1.58      message* envelope = new_message(direct);
    1.59      if (!envelope)
    1.60          return NULL;
    1.61 @@ -479,15 +437,18 @@
    1.62  }
    1.63  
    1.64  static message* wrap_message_as_attachment(message* envelope, 
    1.65 -    const message* attachment) {
    1.66 +    message* attachment) {
    1.67      
    1.68 -    message* _envelope = NULL;
    1.69 +    message* _envelope = envelope;
    1.70      
    1.71 -    if (!envelope) {
    1.72 +    if (!_envelope) {
    1.73          _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
    1.74 -        envelope = _envelope;
    1.75 +        attachment->longmsg = encapsulate_message_wrap_info("INNER", attachment->longmsg);
    1.76 +        _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    1.77      }
    1.78 -    
    1.79 +    else {
    1.80 +        _envelope->longmsg = encapsulate_message_wrap_info("TRANSPORT", _envelope->longmsg);
    1.81 +    }
    1.82      char* message_text = NULL;
    1.83      /* Turn message into a MIME-blob */
    1.84      PEP_STATUS status = mime_encode_message(attachment, false, &message_text);
    1.85 @@ -502,9 +463,9 @@
    1.86      bloblist_t* message_blob = new_bloblist(message_text, message_len,
    1.87                                              "message/rfc822", NULL);
    1.88      
    1.89 -    envelope->attachments = message_blob;
    1.90 +    _envelope->attachments = message_blob;
    1.91      
    1.92 -    return envelope;
    1.93 +    return _envelope;
    1.94  }
    1.95  
    1.96  static PEP_STATUS encrypt_PGP_MIME(
    1.97 @@ -526,14 +487,6 @@
    1.98  
    1.99      if (src->shortmsg)
   1.100          dst->shortmsg = strdup(src->shortmsg);
   1.101 -
   1.102 -    // Right now, we only encrypt inner messages or outer messages. There
   1.103 -    // is no in-between. All messages are to be wrapped or are a wrapper.
   1.104 -    // FIXME: rename this flag!!!
   1.105 -    const char* msg_wrap_info = (flags & PEP_encrypt_flag_inner_message ? 
   1.106 -                                 "INNER" : "OUTER");
   1.107 -    
   1.108 -    ptext = encapsulate_message_wrap_info(msg_wrap_info, src->longmsg);
   1.109          
   1.110      message *_src = calloc(1, sizeof(message));
   1.111      assert(_src);
   1.112 @@ -600,186 +553,6 @@
   1.113      return status;
   1.114  }
   1.115  
   1.116 -// static PEP_STATUS encrypt_PGP_in_pieces(
   1.117 -//     PEP_SESSION session,
   1.118 -//     const message *src,
   1.119 -//     stringlist_t *keys,
   1.120 -//     message *dst,
   1.121 -//     PEP_encrypt_flags_t flags
   1.122 -//     )
   1.123 -// {
   1.124 -//     PEP_STATUS status = PEP_STATUS_OK;
   1.125 -//     char *ctext = NULL;
   1.126 -//     size_t csize;
   1.127 -//     char *ptext = NULL;
   1.128 -//     bool free_ptext = false;
   1.129 -//     unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.130 -//     
   1.131 -//     assert(dst->longmsg == NULL);
   1.132 -//     assert(dst->attachments == NULL);
   1.133 -// 
   1.134 -//     dst->enc_format = PEP_enc_pieces;
   1.135 -// 
   1.136 -//     bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
   1.137 -// 
   1.138 -//     if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0 && 
   1.139 -//         _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) != 0) {
   1.140 -//         if (session->unencrypted_subject) {
   1.141 -//             dst->shortmsg = strdup(src->shortmsg);
   1.142 -//             assert(dst->shortmsg);
   1.143 -//             if (dst->shortmsg == NULL)
   1.144 -//                 goto enomem;
   1.145 -//             ptext = src->longmsg;
   1.146 -//         }
   1.147 -//         else {
   1.148 -//             ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.149 -//             if (ptext == NULL)
   1.150 -//                 goto enomem;
   1.151 -//             free_ptext = true;
   1.152 -//         }
   1.153 -// 
   1.154 -//         if (nosign)
   1.155 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.156 -//                 &csize);
   1.157 -//         else 
   1.158 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.159 -//                 &csize);
   1.160 -//         if (free_ptext)
   1.161 -//             free(ptext);
   1.162 -//         free_ptext = false;
   1.163 -//         if (ctext) {
   1.164 -//             dst->longmsg = ctext;
   1.165 -//         }
   1.166 -//         else {
   1.167 -//             goto pep_error;
   1.168 -//         }
   1.169 -//     }
   1.170 -//     else if (src->longmsg && src->longmsg[0]) {
   1.171 -//         ptext = src->longmsg;
   1.172 -//         if (nosign)
   1.173 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.174 -//                 &csize);
   1.175 -//         else 
   1.176 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.177 -//                 &csize);
   1.178 -//         if (ctext) {
   1.179 -//             dst->longmsg = ctext;
   1.180 -//         }
   1.181 -//         else {
   1.182 -//             goto pep_error;
   1.183 -//         }
   1.184 -//     }
   1.185 -//     else {
   1.186 -//         dst->longmsg = strdup("");
   1.187 -//         assert(dst->longmsg);
   1.188 -//         if (dst->longmsg == NULL)
   1.189 -//             goto enomem;
   1.190 -//     }
   1.191 -// 
   1.192 -//     if (src->longmsg_formatted && src->longmsg_formatted[0]) {
   1.193 -//         ptext = src->longmsg_formatted;
   1.194 -//         if (nosign)
   1.195 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.196 -//                 &csize);
   1.197 -//         else 
   1.198 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.199 -//                 &csize);
   1.200 -//         if (ctext) {
   1.201 -// 
   1.202 -//             bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
   1.203 -//                 "application/octet-stream", "file://PGPexch.htm.pgp");
   1.204 -//             if (_a == NULL)
   1.205 -//                 goto enomem;
   1.206 -//             if (dst->attachments == NULL)
   1.207 -//                 dst->attachments = _a;
   1.208 -//         }
   1.209 -//         else {
   1.210 -//             goto pep_error;
   1.211 -//         }
   1.212 -//     }
   1.213 -// 
   1.214 -//     if (src->attachments) {
   1.215 -//         if (dst->attachments == NULL) {
   1.216 -//             dst->attachments = new_bloblist(NULL, 0, NULL, NULL);
   1.217 -//             if (dst->attachments == NULL)
   1.218 -//                 goto enomem;
   1.219 -//         }
   1.220 -// 
   1.221 -//         bloblist_t *_s = src->attachments;
   1.222 -//         bloblist_t *_d = dst->attachments;
   1.223 -// 
   1.224 -//         for (int n = 0; _s; _s = _s->next) {
   1.225 -//             if (_s->value == NULL && _s->size == 0) {
   1.226 -//                 _d = bloblist_add(_d, NULL, 0, _s->mime_type, _s->filename);
   1.227 -//                 if (_d == NULL)
   1.228 -//                     goto enomem;
   1.229 -//             }
   1.230 -//             else {
   1.231 -//                 size_t psize = _s->size;
   1.232 -//                 ptext = _s->value;
   1.233 -//                 if (nosign)
   1.234 -//                     status = encrypt_only(session, keys, ptext, psize, &ctext,
   1.235 -//                         &csize);
   1.236 -//                 else 
   1.237 -//                     status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.238 -//                         &csize);
   1.239 -//                 if (ctext) {
   1.240 -//                     char *filename = NULL;
   1.241 -// 
   1.242 -//                     char *attach_fn = _s->filename;
   1.243 -//                     if (attach_fn && !is_cid_uri(attach_fn)) {
   1.244 -//                         size_t len = strlen(_s->filename);
   1.245 -//                         size_t bufsize = len + 5; // length of .pgp extension + NUL
   1.246 -//                         bool already_uri = false;
   1.247 -//                         if (is_file_uri(attach_fn))
   1.248 -//                             already_uri = true;
   1.249 -//                         else
   1.250 -//                             bufsize += 7; // length of file://
   1.251 -//                             
   1.252 -//                         filename = calloc(1, bufsize);
   1.253 -//                         if (filename == NULL)
   1.254 -//                             goto enomem;
   1.255 -// 
   1.256 -//                         if (!already_uri)
   1.257 -//                             strlcpy(filename, "file://", bufsize);
   1.258 -//                         // First char is NUL, so we're ok, even if not copying above. (calloc)
   1.259 -//                         strlcat(filename, _s->filename, bufsize);
   1.260 -//                         strlcat(filename, ".pgp", bufsize);
   1.261 -//                     }
   1.262 -//                     else {
   1.263 -//                         filename = calloc(1, 27);
   1.264 -//                         if (filename == NULL)
   1.265 -//                             goto enomem;
   1.266 -// 
   1.267 -//                         ++n;
   1.268 -//                         n &= 0xffff;
   1.269 -//                         snprintf(filename, 20, "file://Attachment%d.pgp", n);
   1.270 -//                     }
   1.271 -// 
   1.272 -//                     _d = bloblist_add(_d, ctext, csize, "application/octet-stream",
   1.273 -//                         filename);
   1.274 -//                     free(filename);
   1.275 -//                     if (_d == NULL)
   1.276 -//                         goto enomem;
   1.277 -//                 }
   1.278 -//                 else {
   1.279 -//                     goto pep_error;
   1.280 -//                 }
   1.281 -//             }
   1.282 -//         }
   1.283 -//     }
   1.284 -// 
   1.285 -//     return PEP_STATUS_OK;
   1.286 -// 
   1.287 -// enomem:
   1.288 -//     status = PEP_OUT_OF_MEMORY;
   1.289 -// 
   1.290 -// pep_error:
   1.291 -//     if (free_ptext)
   1.292 -//         free(ptext);
   1.293 -//     return status;
   1.294 -// }
   1.295 -
   1.296  static char * keylist_to_string(const stringlist_t *keylist)
   1.297  {
   1.298      if (keylist) {
   1.299 @@ -1264,7 +1037,6 @@
   1.300      PEP_STATUS status = PEP_STATUS_OK;
   1.301      message * msg = NULL;
   1.302      stringlist_t * keys = NULL;
   1.303 -    message* inner_message = NULL;
   1.304      message* _src = src;
   1.305      
   1.306      assert(session);
   1.307 @@ -1393,18 +1165,13 @@
   1.308          return ADD_TO_LOG(PEP_UNENCRYPTED);
   1.309      }
   1.310      else {
   1.311 -        
   1.312 -        // FIXME - this logic may need to change if we allow
   1.313 -        // wrappers to attach keys (e.g w/ transport)        
   1.314 -        if (!(flags & PEP_encrypt_flag_inner_message)) {
   1.315 -            PEP_STATUS status = encrypt_message(session, src, extra, &inner_message,
   1.316 -                                                enc_format,
   1.317 -                                                flags | PEP_encrypt_flag_inner_message);
   1.318 -            _src = wrap_message_as_attachment(NULL, inner_message);
   1.319 -        } else {
   1.320 -            if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.321 -                attach_own_key(session, _src);
   1.322 +        // FIXME - we need to deal with transport types (via flag)
   1.323 +        if ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp) {
   1.324 +            _src = wrap_message_as_attachment(NULL, src);
   1.325          }
   1.326 +        if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.327 +            attach_own_key(session, _src);
   1.328 +
   1.329          msg = clone_to_empty_message(_src);
   1.330          if (msg == NULL)
   1.331              goto enomem;
   1.332 @@ -2321,57 +2088,68 @@
   1.333          if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   1.334              char* wrap_info = NULL;
   1.335              status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   1.336 +
   1.337 +            bool is_transport_wrapper = false;
   1.338              
   1.339              // FIXME: replace with enums, check status
   1.340              if (wrap_info) {
   1.341                  if (strcmp(wrap_info, "OUTER") == 0) {
   1.342                      // this only occurs in with a direct outer wrapper
   1.343                      // where the actual content is in the inner wrapper
   1.344 -                    
   1.345 +                    message* inner_message = NULL;                    
   1.346                      bloblist_t* actual_message = msg->attachments;
   1.347                      
   1.348                      while (actual_message) {
   1.349                          char* mime_type = actual_message->mime_type;
   1.350                          if (mime_type) {
   1.351 +                            
   1.352                              // libetpan appears to change the mime_type on this one.
   1.353                              // *growl*
   1.354                              if (strcmp("message/rfc822", mime_type) == 0 ||
   1.355 -                                strcmp("text/rfc822", mime_type) == 0)
   1.356 -                                break;
   1.357 +                                strcmp("text/rfc822", mime_type) == 0) {
   1.358 +                                    
   1.359 +                                status = mime_decode_message(actual_message->value, 
   1.360 +                                                             actual_message->size, 
   1.361 +                                                             &inner_message);
   1.362 +                                if (status != PEP_STATUS_OK)
   1.363 +                                    GOTO(pep_error);
   1.364 +                                
   1.365 +                                if (inner_message) {
   1.366 +                                    // Though this will strip any message info on the
   1.367 +                                    // attachment, this is safe, as we do not
   1.368 +                                    // produce more than one attachment-as-message,
   1.369 +                                    // and those are the only ones with such info.
   1.370 +                                    // Since we capture the information, this is ok.
   1.371 +                                    wrap_info = NULL;
   1.372 +                                    // FIXME
   1.373 +                                    status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   1.374 +                                    if (wrap_info) {
   1.375 +                                        // useless check, but just in case we screw up?
   1.376 +                                        if (strcmp(wrap_info, "INNER") == 0) {
   1.377 +                                            // THIS is our message
   1.378 +                                            src = msg = inner_message;
   1.379 +                                            break;        
   1.380 +                                        }
   1.381 +                                        else { // should never happen
   1.382 +                                            status = PEP_UNKNOWN_ERROR;
   1.383 +                                            free_message(inner_message);
   1.384 +                                            GOTO(pep_error);
   1.385 +                                        }
   1.386 +                                    }
   1.387 +                                }
   1.388 +                                else { // forwarded message, leave it alone
   1.389 +                                    free_message(inner_message);
   1.390 +                                }
   1.391 +                            }
   1.392                          }
   1.393                          actual_message = actual_message->next;
   1.394 -                    }
   1.395 -                    
   1.396 -                    if (actual_message) {
   1.397 -                        message* inner_message = NULL;
   1.398 -                        status = mime_decode_message(actual_message->value, 
   1.399 -                                                     actual_message->size, 
   1.400 -                                                     &inner_message);
   1.401 -                        if (status != PEP_STATUS_OK)
   1.402 -                            GOTO(pep_error);
   1.403 -                            
   1.404 -                        free_stringlist(*keylist);
   1.405 -                        *keylist == NULL;
   1.406 -                        
   1.407 -                        free_message(*dst);
   1.408 -                        
   1.409 -                        *dst = NULL;
   1.410 -                        *rating = PEP_rating_undefined;
   1.411 -                        *flags = 0;
   1.412 -
   1.413 -                        message* inner_dec_msg = NULL;
   1.414 -                        
   1.415 -                        decrypt_status = decrypt_message(session,
   1.416 -                                                         inner_message,
   1.417 -                                                         &inner_dec_msg,
   1.418 -                                                         keylist,
   1.419 -                                                         rating,
   1.420 -                                                         flags);
   1.421 -                                                         
   1.422 -                        *dst = inner_dec_msg;
   1.423 -                        return decrypt_status;
   1.424 -                    }
   1.425 +                    }                    
   1.426                  }
   1.427 +                else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   1.428 +                    // FIXME: this gets even messier.
   1.429 +                    // (TBI in ENGINE-278)
   1.430 +                }
   1.431 +                else {} // shouldn't be anything to be done here
   1.432              }
   1.433          }
   1.434          
   1.435 @@ -2428,7 +2206,7 @@
   1.436          }
   1.437          
   1.438          // copy message id to output message        
   1.439 -        if (src->id) {
   1.440 +        if (src->id && src != msg) {
   1.441              msg->id = strdup(src->id);
   1.442              assert(msg->id);
   1.443              if (msg->id == NULL)
     2.1 --- a/src/pEpEngine.h	Tue Oct 10 15:03:17 2017 +0200
     2.2 +++ b/src/pEpEngine.h	Wed Oct 11 15:35:52 2017 +0200
     2.3 @@ -16,7 +16,7 @@
     2.4  #include "stringpair.h"    
     2.5  #include "timestamp.h"
     2.6  
     2.7 -#define PEP_VERSION "1.0" // protocol version
     2.8 +#define PEP_VERSION "2.0" // protocol version
     2.9  
    2.10  #define PEP_OWN_USERID "pEp_own_userId"
    2.11      
     3.1 --- a/test/revoke_regen_attach_test.cc	Tue Oct 10 15:03:17 2017 +0200
     3.2 +++ b/test/revoke_regen_attach_test.cc	Wed Oct 11 15:35:52 2017 +0200
     3.3 @@ -61,7 +61,6 @@
     3.4      message *enc_msg;
     3.5      cout << "calling encrypt_message()\n";
     3.6      status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
     3.7 -    cout << status;
     3.8      assert(status == PEP_STATUS_OK);
     3.9      assert(enc_msg);
    3.10      cout << "message encrypted.\n";
    3.11 @@ -71,7 +70,7 @@
    3.12      assert(strcmp(msg->attachments->filename, "file://pEpkey.asc") == 0);
    3.13      assert(strcmp(msg->attachments->next->filename, "file://pEpkey.asc") == 0);
    3.14  
    3.15 -    cout << "message contains 2 key attachements.\n";
    3.16 +    cout << "message contains 2 key attachments.\n";
    3.17  
    3.18      free_message(msg);
    3.19      free_message(enc_msg);