ENGINE-214: encode/encrypt in place (but untested/uncompiled). ENGINE-214
authorKrista Bennett <krista@pep-project.org>
Fri, 29 Sep 2017 19:47:41 +0200
branchENGINE-214
changeset 21213e2d2c40c229
parent 2120 b99308bd100a
child 2122 e570aa766e5f
ENGINE-214: encode/encrypt in place (but untested/uncompiled).
src/message_api.c
src/message_api.h
     1.1 --- a/src/message_api.c	Wed Sep 27 18:28:42 2017 +0200
     1.2 +++ b/src/message_api.c	Fri Sep 29 19:47:41 2017 +0200
     1.3 @@ -408,6 +408,49 @@
     1.4      return PEP_STATUS_OK;
     1.5  }
     1.6  
     1.7 +
     1.8 +static message* extract_minimal_envelope(const message* src, 
     1.9 +                                         PEP_msg_direction direct) {
    1.10 +                                             
    1.11 +    unsigned char pepstr[] = PEP_SUBJ_STRING;
    1.12 +    
    1.13 +    message* envelope = new_message(direct);
    1.14 +    if (!envelope)
    1.15 +        return NULL;
    1.16 +        
    1.17 +    envelope->shortmsg = _pep_subj_copy();
    1.18 +    if (!envelope->shortmsg)
    1.19 +        return NULL;
    1.20 +
    1.21 +    if (src->from) {
    1.22 +        envelope->from = identity_dup(src->from);
    1.23 +        if (!envelope->from)
    1.24 +            return NULL;
    1.25 +    }
    1.26 +
    1.27 +    if (src->to) {
    1.28 +        envelope->to = identity_list_dup(src->to);
    1.29 +        if (!envelope->to)
    1.30 +            return NULL;
    1.31 +    }
    1.32 +
    1.33 +    if (src->cc) {
    1.34 +        envelope->cc = identity_list_dup(src->cc);
    1.35 +        if (!envelope->cc)
    1.36 +            return NULL;
    1.37 +    }
    1.38 +
    1.39 +    if (src->bcc) {
    1.40 +        envelope->bcc = identity_list_dup(src->bcc);
    1.41 +        if (!envelope->bcc)
    1.42 +            return NULL;
    1.43 +    }
    1.44 +
    1.45 +    envelope->enc_format = src->enc_format;        
    1.46 +    
    1.47 +    return envelope;
    1.48 +}
    1.49 +
    1.50  static message * clone_to_empty_message(const message * src)
    1.51  {
    1.52      PEP_STATUS status;
    1.53 @@ -435,6 +478,35 @@
    1.54      return NULL;
    1.55  }
    1.56  
    1.57 +static message* wrap_message_as_attachment(message* envelope, 
    1.58 +    const message* attachment) {
    1.59 +    
    1.60 +    message* _envelope = NULL;
    1.61 +    
    1.62 +    if (!envelope) {
    1.63 +        _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
    1.64 +        envelope = _envelope;
    1.65 +    }
    1.66 +    
    1.67 +    char* message_text = NULL;
    1.68 +    /* Turn message into a MIME-blob */
    1.69 +    PEP_STATUS status = mime_encode_message(attachment, false, &message_text);
    1.70 +    
    1.71 +    if (status != PEP_STATUS_OK) {
    1.72 +        free(_envelope);
    1.73 +        return NULL;
    1.74 +    }
    1.75 +    
    1.76 +    size_t message_len = strlen(message_text);
    1.77 +    
    1.78 +    bloblist_t* message_blob = new_bloblist(message_text, message_len,
    1.79 +                                            "message/rfc822", NULL);
    1.80 +    
    1.81 +    envelope->attachments = message_blob;
    1.82 +    
    1.83 +    return envelope;
    1.84 +}
    1.85 +
    1.86  static PEP_STATUS encrypt_PGP_MIME(
    1.87      PEP_SESSION session,
    1.88      const message *src,
    1.89 @@ -451,15 +523,14 @@
    1.90      size_t csize;
    1.91      assert(dst->longmsg == NULL);
    1.92      dst->enc_format = PEP_enc_PGP_MIME;
    1.93 -    unsigned char pepstr[] = PEP_SUBJ_STRING;
    1.94  
    1.95      if (src->shortmsg)
    1.96          dst->shortmsg = strdup(src->shortmsg);
    1.97  
    1.98      // Right now, we only encrypt inner messages or outer messages. There
    1.99      // is no in-between. All messages are to be wrapped or are a wrapper.
   1.100 -    const char* msg_wrap_info = (flags & PEP_encrypt_flag_wrap_message ? 
   1.101 -                                 "INNER" : "OUTER");
   1.102 +    const char* msg_wrap_info = (flags & PEP_encrypt_flag_no_wrap_message ? 
   1.103 +                                 "OUTER" : "INNER");
   1.104      
   1.105      ptext = encapsulate_message_wrap_info(const char *msg_wrap_info, src->longmsg);
   1.106          
   1.107 @@ -528,185 +599,185 @@
   1.108      return status;
   1.109  }
   1.110  
   1.111 -static PEP_STATUS encrypt_PGP_in_pieces(
   1.112 -    PEP_SESSION session,
   1.113 -    const message *src,
   1.114 -    stringlist_t *keys,
   1.115 -    message *dst,
   1.116 -    PEP_encrypt_flags_t flags
   1.117 -    )
   1.118 -{
   1.119 -    PEP_STATUS status = PEP_STATUS_OK;
   1.120 -    char *ctext = NULL;
   1.121 -    size_t csize;
   1.122 -    char *ptext = NULL;
   1.123 -    bool free_ptext = false;
   1.124 -    unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.125 -    
   1.126 -    assert(dst->longmsg == NULL);
   1.127 -    assert(dst->attachments == NULL);
   1.128 -
   1.129 -    dst->enc_format = PEP_enc_pieces;
   1.130 -
   1.131 -    bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
   1.132 -
   1.133 -    if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0 && 
   1.134 -        _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) != 0) {
   1.135 -        if (session->unencrypted_subject) {
   1.136 -            dst->shortmsg = strdup(src->shortmsg);
   1.137 -            assert(dst->shortmsg);
   1.138 -            if (dst->shortmsg == NULL)
   1.139 -                goto enomem;
   1.140 -            ptext = src->longmsg;
   1.141 -        }
   1.142 -        else {
   1.143 -            ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.144 -            if (ptext == NULL)
   1.145 -                goto enomem;
   1.146 -            free_ptext = true;
   1.147 -        }
   1.148 -
   1.149 -        if (nosign)
   1.150 -            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.151 -                &csize);
   1.152 -        else 
   1.153 -            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.154 -                &csize);
   1.155 -        if (free_ptext)
   1.156 -            free(ptext);
   1.157 -        free_ptext = false;
   1.158 -        if (ctext) {
   1.159 -            dst->longmsg = ctext;
   1.160 -        }
   1.161 -        else {
   1.162 -            goto pep_error;
   1.163 -        }
   1.164 -    }
   1.165 -    else if (src->longmsg && src->longmsg[0]) {
   1.166 -        ptext = src->longmsg;
   1.167 -        if (nosign)
   1.168 -            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.169 -                &csize);
   1.170 -        else 
   1.171 -            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.172 -                &csize);
   1.173 -        if (ctext) {
   1.174 -            dst->longmsg = ctext;
   1.175 -        }
   1.176 -        else {
   1.177 -            goto pep_error;
   1.178 -        }
   1.179 -    }
   1.180 -    else {
   1.181 -        dst->longmsg = strdup("");
   1.182 -        assert(dst->longmsg);
   1.183 -        if (dst->longmsg == NULL)
   1.184 -            goto enomem;
   1.185 -    }
   1.186 -
   1.187 -    if (src->longmsg_formatted && src->longmsg_formatted[0]) {
   1.188 -        ptext = src->longmsg_formatted;
   1.189 -        if (nosign)
   1.190 -            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.191 -                &csize);
   1.192 -        else 
   1.193 -            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.194 -                &csize);
   1.195 -        if (ctext) {
   1.196 -
   1.197 -            bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
   1.198 -                "application/octet-stream", "file://PGPexch.htm.pgp");
   1.199 -            if (_a == NULL)
   1.200 -                goto enomem;
   1.201 -            if (dst->attachments == NULL)
   1.202 -                dst->attachments = _a;
   1.203 -        }
   1.204 -        else {
   1.205 -            goto pep_error;
   1.206 -        }
   1.207 -    }
   1.208 -
   1.209 -    if (src->attachments) {
   1.210 -        if (dst->attachments == NULL) {
   1.211 -            dst->attachments = new_bloblist(NULL, 0, NULL, NULL);
   1.212 -            if (dst->attachments == NULL)
   1.213 -                goto enomem;
   1.214 -        }
   1.215 -
   1.216 -        bloblist_t *_s = src->attachments;
   1.217 -        bloblist_t *_d = dst->attachments;
   1.218 -
   1.219 -        for (int n = 0; _s; _s = _s->next) {
   1.220 -            if (_s->value == NULL && _s->size == 0) {
   1.221 -                _d = bloblist_add(_d, NULL, 0, _s->mime_type, _s->filename);
   1.222 -                if (_d == NULL)
   1.223 -                    goto enomem;
   1.224 -            }
   1.225 -            else {
   1.226 -                size_t psize = _s->size;
   1.227 -                ptext = _s->value;
   1.228 -                if (nosign)
   1.229 -                    status = encrypt_only(session, keys, ptext, psize, &ctext,
   1.230 -                        &csize);
   1.231 -                else 
   1.232 -                    status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.233 -                        &csize);
   1.234 -                if (ctext) {
   1.235 -                    char *filename = NULL;
   1.236 -
   1.237 -                    char *attach_fn = _s->filename;
   1.238 -                    if (attach_fn && !is_cid_uri(attach_fn)) {
   1.239 -                        size_t len = strlen(_s->filename);
   1.240 -                        size_t bufsize = len + 5; // length of .pgp extension + NUL
   1.241 -                        bool already_uri = false;
   1.242 -                        if (is_file_uri(attach_fn))
   1.243 -                            already_uri = true;
   1.244 -                        else
   1.245 -                            bufsize += 7; // length of file://
   1.246 -                            
   1.247 -                        filename = calloc(1, bufsize);
   1.248 -                        if (filename == NULL)
   1.249 -                            goto enomem;
   1.250 -
   1.251 -                        if (!already_uri)
   1.252 -                            strlcpy(filename, "file://", bufsize);
   1.253 -                        // First char is NUL, so we're ok, even if not copying above. (calloc)
   1.254 -                        strlcat(filename, _s->filename, bufsize);
   1.255 -                        strlcat(filename, ".pgp", bufsize);
   1.256 -                    }
   1.257 -                    else {
   1.258 -                        filename = calloc(1, 27);
   1.259 -                        if (filename == NULL)
   1.260 -                            goto enomem;
   1.261 -
   1.262 -                        ++n;
   1.263 -                        n &= 0xffff;
   1.264 -                        snprintf(filename, 20, "file://Attachment%d.pgp", n);
   1.265 -                    }
   1.266 -
   1.267 -                    _d = bloblist_add(_d, ctext, csize, "application/octet-stream",
   1.268 -                        filename);
   1.269 -                    free(filename);
   1.270 -                    if (_d == NULL)
   1.271 -                        goto enomem;
   1.272 -                }
   1.273 -                else {
   1.274 -                    goto pep_error;
   1.275 -                }
   1.276 -            }
   1.277 -        }
   1.278 -    }
   1.279 -
   1.280 -    return PEP_STATUS_OK;
   1.281 -
   1.282 -enomem:
   1.283 -    status = PEP_OUT_OF_MEMORY;
   1.284 -
   1.285 -pep_error:
   1.286 -    if (free_ptext)
   1.287 -        free(ptext);
   1.288 -    return status;
   1.289 -}
   1.290 +// static PEP_STATUS encrypt_PGP_in_pieces(
   1.291 +//     PEP_SESSION session,
   1.292 +//     const message *src,
   1.293 +//     stringlist_t *keys,
   1.294 +//     message *dst,
   1.295 +//     PEP_encrypt_flags_t flags
   1.296 +//     )
   1.297 +// {
   1.298 +//     PEP_STATUS status = PEP_STATUS_OK;
   1.299 +//     char *ctext = NULL;
   1.300 +//     size_t csize;
   1.301 +//     char *ptext = NULL;
   1.302 +//     bool free_ptext = false;
   1.303 +//     unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.304 +//     
   1.305 +//     assert(dst->longmsg == NULL);
   1.306 +//     assert(dst->attachments == NULL);
   1.307 +// 
   1.308 +//     dst->enc_format = PEP_enc_pieces;
   1.309 +// 
   1.310 +//     bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
   1.311 +// 
   1.312 +//     if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0 && 
   1.313 +//         _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) != 0) {
   1.314 +//         if (session->unencrypted_subject) {
   1.315 +//             dst->shortmsg = strdup(src->shortmsg);
   1.316 +//             assert(dst->shortmsg);
   1.317 +//             if (dst->shortmsg == NULL)
   1.318 +//                 goto enomem;
   1.319 +//             ptext = src->longmsg;
   1.320 +//         }
   1.321 +//         else {
   1.322 +//             ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.323 +//             if (ptext == NULL)
   1.324 +//                 goto enomem;
   1.325 +//             free_ptext = true;
   1.326 +//         }
   1.327 +// 
   1.328 +//         if (nosign)
   1.329 +//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.330 +//                 &csize);
   1.331 +//         else 
   1.332 +//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.333 +//                 &csize);
   1.334 +//         if (free_ptext)
   1.335 +//             free(ptext);
   1.336 +//         free_ptext = false;
   1.337 +//         if (ctext) {
   1.338 +//             dst->longmsg = ctext;
   1.339 +//         }
   1.340 +//         else {
   1.341 +//             goto pep_error;
   1.342 +//         }
   1.343 +//     }
   1.344 +//     else if (src->longmsg && src->longmsg[0]) {
   1.345 +//         ptext = src->longmsg;
   1.346 +//         if (nosign)
   1.347 +//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.348 +//                 &csize);
   1.349 +//         else 
   1.350 +//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.351 +//                 &csize);
   1.352 +//         if (ctext) {
   1.353 +//             dst->longmsg = ctext;
   1.354 +//         }
   1.355 +//         else {
   1.356 +//             goto pep_error;
   1.357 +//         }
   1.358 +//     }
   1.359 +//     else {
   1.360 +//         dst->longmsg = strdup("");
   1.361 +//         assert(dst->longmsg);
   1.362 +//         if (dst->longmsg == NULL)
   1.363 +//             goto enomem;
   1.364 +//     }
   1.365 +// 
   1.366 +//     if (src->longmsg_formatted && src->longmsg_formatted[0]) {
   1.367 +//         ptext = src->longmsg_formatted;
   1.368 +//         if (nosign)
   1.369 +//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.370 +//                 &csize);
   1.371 +//         else 
   1.372 +//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.373 +//                 &csize);
   1.374 +//         if (ctext) {
   1.375 +// 
   1.376 +//             bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
   1.377 +//                 "application/octet-stream", "file://PGPexch.htm.pgp");
   1.378 +//             if (_a == NULL)
   1.379 +//                 goto enomem;
   1.380 +//             if (dst->attachments == NULL)
   1.381 +//                 dst->attachments = _a;
   1.382 +//         }
   1.383 +//         else {
   1.384 +//             goto pep_error;
   1.385 +//         }
   1.386 +//     }
   1.387 +// 
   1.388 +//     if (src->attachments) {
   1.389 +//         if (dst->attachments == NULL) {
   1.390 +//             dst->attachments = new_bloblist(NULL, 0, NULL, NULL);
   1.391 +//             if (dst->attachments == NULL)
   1.392 +//                 goto enomem;
   1.393 +//         }
   1.394 +// 
   1.395 +//         bloblist_t *_s = src->attachments;
   1.396 +//         bloblist_t *_d = dst->attachments;
   1.397 +// 
   1.398 +//         for (int n = 0; _s; _s = _s->next) {
   1.399 +//             if (_s->value == NULL && _s->size == 0) {
   1.400 +//                 _d = bloblist_add(_d, NULL, 0, _s->mime_type, _s->filename);
   1.401 +//                 if (_d == NULL)
   1.402 +//                     goto enomem;
   1.403 +//             }
   1.404 +//             else {
   1.405 +//                 size_t psize = _s->size;
   1.406 +//                 ptext = _s->value;
   1.407 +//                 if (nosign)
   1.408 +//                     status = encrypt_only(session, keys, ptext, psize, &ctext,
   1.409 +//                         &csize);
   1.410 +//                 else 
   1.411 +//                     status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.412 +//                         &csize);
   1.413 +//                 if (ctext) {
   1.414 +//                     char *filename = NULL;
   1.415 +// 
   1.416 +//                     char *attach_fn = _s->filename;
   1.417 +//                     if (attach_fn && !is_cid_uri(attach_fn)) {
   1.418 +//                         size_t len = strlen(_s->filename);
   1.419 +//                         size_t bufsize = len + 5; // length of .pgp extension + NUL
   1.420 +//                         bool already_uri = false;
   1.421 +//                         if (is_file_uri(attach_fn))
   1.422 +//                             already_uri = true;
   1.423 +//                         else
   1.424 +//                             bufsize += 7; // length of file://
   1.425 +//                             
   1.426 +//                         filename = calloc(1, bufsize);
   1.427 +//                         if (filename == NULL)
   1.428 +//                             goto enomem;
   1.429 +// 
   1.430 +//                         if (!already_uri)
   1.431 +//                             strlcpy(filename, "file://", bufsize);
   1.432 +//                         // First char is NUL, so we're ok, even if not copying above. (calloc)
   1.433 +//                         strlcat(filename, _s->filename, bufsize);
   1.434 +//                         strlcat(filename, ".pgp", bufsize);
   1.435 +//                     }
   1.436 +//                     else {
   1.437 +//                         filename = calloc(1, 27);
   1.438 +//                         if (filename == NULL)
   1.439 +//                             goto enomem;
   1.440 +// 
   1.441 +//                         ++n;
   1.442 +//                         n &= 0xffff;
   1.443 +//                         snprintf(filename, 20, "file://Attachment%d.pgp", n);
   1.444 +//                     }
   1.445 +// 
   1.446 +//                     _d = bloblist_add(_d, ctext, csize, "application/octet-stream",
   1.447 +//                         filename);
   1.448 +//                     free(filename);
   1.449 +//                     if (_d == NULL)
   1.450 +//                         goto enomem;
   1.451 +//                 }
   1.452 +//                 else {
   1.453 +//                     goto pep_error;
   1.454 +//                 }
   1.455 +//             }
   1.456 +//         }
   1.457 +//     }
   1.458 +// 
   1.459 +//     return PEP_STATUS_OK;
   1.460 +// 
   1.461 +// enomem:
   1.462 +//     status = PEP_OUT_OF_MEMORY;
   1.463 +// 
   1.464 +// pep_error:
   1.465 +//     if (free_ptext)
   1.466 +//         free(ptext);
   1.467 +//     return status;
   1.468 +// }
   1.469  
   1.470  static char * keylist_to_string(const stringlist_t *keylist)
   1.471  {
   1.472 @@ -1192,7 +1263,9 @@
   1.473      PEP_STATUS status = PEP_STATUS_OK;
   1.474      message * msg = NULL;
   1.475      stringlist_t * keys = NULL;
   1.476 -
   1.477 +    message* inner_message = NULL;
   1.478 +    message* _src = src;
   1.479 +    
   1.480      assert(session);
   1.481      assert(src);
   1.482      assert(dst);
   1.483 @@ -1319,31 +1392,40 @@
   1.484          return ADD_TO_LOG(PEP_UNENCRYPTED);
   1.485      }
   1.486      else {
   1.487 -        msg = clone_to_empty_message(src);
   1.488 +        
   1.489 +        // FIXME - this logic may need to change if we allow
   1.490 +        // wrappers to attach keys (e.g w/ transport)        
   1.491 +        if (!(flags & PEP_encrypt_flag_no_wrap_message)) {
   1.492 +            PEP_STATUS status = encrypt_message(session, src, extra, &inner_message,
   1.493 +                                                enc_format,
   1.494 +                                                flags & PEP_encrypt_flag_no_wrap_message);
   1.495 +            _src = wrap_message_as_attachment(NULL, inner_message);
   1.496 +        } else {
   1.497 +            if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.498 +                attach_own_key(session, _src);
   1.499 +        }
   1.500 +        msg = clone_to_empty_message(_src);
   1.501          if (msg == NULL)
   1.502              goto enomem;
   1.503  
   1.504 -        if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.505 -            attach_own_key(session, src);
   1.506 -
   1.507          switch (enc_format) {
   1.508 -        case PEP_enc_PGP_MIME:
   1.509 -        case PEP_enc_PEP: // BUG: should be implemented extra
   1.510 -            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   1.511 -            break;
   1.512 -
   1.513 -        case PEP_enc_pieces:
   1.514 -            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   1.515 -            break;
   1.516 -
   1.517 -        /* case PEP_enc_PEP:
   1.518 -            // TODO: implement
   1.519 -            NOT_IMPLEMENTED */
   1.520 -
   1.521 -        default:
   1.522 -            assert(0);
   1.523 -            status = PEP_ILLEGAL_VALUE;
   1.524 -            GOTO(pep_error);
   1.525 +            case PEP_enc_PGP_MIME:
   1.526 +            case PEP_enc_PEP: // BUG: should be implemented extra
   1.527 +                status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   1.528 +                break;
   1.529 +
   1.530 +            // case PEP_enc_pieces:
   1.531 +            //     status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   1.532 +            //     break;
   1.533 +
   1.534 +            /* case PEP_enc_PEP:
   1.535 +                // TODO: implement
   1.536 +                NOT_IMPLEMENTED */
   1.537 +
   1.538 +            default:
   1.539 +                assert(0);
   1.540 +                status = PEP_ILLEGAL_VALUE;
   1.541 +                GOTO(pep_error);
   1.542          }
   1.543  
   1.544          if (status == PEP_OUT_OF_MEMORY)
   1.545 @@ -1356,7 +1438,7 @@
   1.546      free_stringlist(keys);
   1.547  
   1.548      if (msg && msg->shortmsg == NULL) {
   1.549 -        msg->shortmsg = _pep_subj_copy();
   1.550 +        msg->shortmsg = strdup("");
   1.551          assert(msg->shortmsg);
   1.552          if (msg->shortmsg == NULL)
   1.553              goto enomem;
   1.554 @@ -1373,6 +1455,12 @@
   1.555      }
   1.556  
   1.557      *dst = msg;
   1.558 +    
   1.559 +    // ??? FIXME: Check to be sure we don't have references btw _src and msg. 
   1.560 +    // I don't think we do.
   1.561 +    if (_src && _src != src)
   1.562 +        free_message(_src);
   1.563 +        
   1.564      return ADD_TO_LOG(status);
   1.565  
   1.566  enomem:
   1.567 @@ -1381,10 +1469,14 @@
   1.568  pep_error:
   1.569      free_stringlist(keys);
   1.570      free_message(msg);
   1.571 +    if (_src && _src != src)
   1.572 +        free_message(_src);
   1.573  
   1.574      return ADD_TO_LOG(status);
   1.575  }
   1.576  
   1.577 +
   1.578 +// FIXME: Update if needed for the wrapped fun bits
   1.579  DYNAMIC_API PEP_STATUS encrypt_message_for_self(
   1.580          PEP_SESSION session,
   1.581          pEp_identity* target_id,
   1.582 @@ -1446,9 +1538,9 @@
   1.583              status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   1.584              break;
   1.585  
   1.586 -        case PEP_enc_pieces:
   1.587 -            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   1.588 -            break;
   1.589 +        // case PEP_enc_pieces:
   1.590 +        //     status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   1.591 +        //     break;
   1.592  
   1.593          /* case PEP_enc_PEP:
   1.594              NOT_IMPLEMENTED */
     2.1 --- a/src/message_api.h	Wed Sep 27 18:28:42 2017 +0200
     2.2 +++ b/src/message_api.h	Fri Sep 29 19:47:41 2017 +0200
     2.3 @@ -33,7 +33,11 @@
     2.4      // This flag is for special use cases and should not be used
     2.5      // by normal pEp clients!
     2.6      PEP_encrypt_flag_force_unsigned = 0x2,
     2.7 -    PEP_encrypt_flag_force_no_attached_key = 0x4
     2.8 +    PEP_encrypt_flag_force_no_attached_key = 0x4,
     2.9 +    
    2.10 +    // This is used for outer messages (used to wrap the real message)
    2.11 +    // This is only used internally and (eventually) by transport functions
    2.12 +    PEP_encrypt_flag_no_wrap_message = 0x8
    2.13  } PEP_encrypt_flags; 
    2.14  
    2.15  typedef unsigned int PEP_encrypt_flags_t;