Merged in ENGINE-559 ENGINE-551
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 07 Aug 2019 12:00:56 +0200
branchENGINE-551
changeset 39507ee96089a3ff
parent 3949 571afb5abe5f
parent 3948 371c29c97a53
child 3952 ade4498550a1
Merged in ENGINE-559
src/message_api.c
test/src/SuiteMaker.cc
     1.1 --- a/src/etpan_mime.c	Wed Aug 07 11:55:15 2019 +0200
     1.2 +++ b/src/etpan_mime.c	Wed Aug 07 12:00:56 2019 +0200
     1.3 @@ -390,7 +390,7 @@
     1.4      stringpair_list_t* extra_params = NULL;
     1.5      
     1.6      if (set_attachment_forward_comment)
     1.7 -        extra_params = new_stringpair_list(new_stringpair("forward", "no"));
     1.8 +        extra_params = new_stringpair_list(new_stringpair("forwarded", "no"));
     1.9      
    1.10      mime = part_new_empty(content, mime_fields, extra_params, 1);
    1.11      free_stringpair_list(extra_params);
    1.12 @@ -2628,7 +2628,7 @@
    1.13                              for (cur = clist_begin(content->ct_parameters); cur; cur =
    1.14                                   clist_next(cur)) {
    1.15                                  struct mailmime_parameter * param = clist_content(cur);
    1.16 -                                if (param && param->pa_name && strcasecmp(param->pa_name, "forward") == 0) {
    1.17 +                                if (param && param->pa_name && strcasecmp(param->pa_name, "forwarded") == 0) {
    1.18                                      if (param->pa_value && strcasecmp(param->pa_value, "no") == 0) {
    1.19                                          *raise_msg_attachment = true;
    1.20                                          break;
     2.1 --- a/src/keymanagement.c	Wed Aug 07 11:55:15 2019 +0200
     2.2 +++ b/src/keymanagement.c	Wed Aug 07 12:00:56 2019 +0200
     2.3 @@ -454,7 +454,11 @@
     2.4      
     2.5      if (pEp_user) {
     2.6          PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
     2.7 -        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;    
     2.8 +        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
     2.9 +        if (identity->major_ver == 0) {
    2.10 +            identity->major_ver = 2;
    2.11 +            identity->minor_ver = 0;
    2.12 +        }    
    2.13      }
    2.14  }
    2.15  
    2.16 @@ -528,6 +532,9 @@
    2.17      
    2.18      return_id->me = stored_ident->me;
    2.19      
    2.20 +    return_id->major_ver = stored_ident->major_ver;
    2.21 +    return_id->minor_ver = stored_ident->minor_ver;
    2.22 +
    2.23      // FIXME: Do we ALWAYS do this? We probably should...
    2.24      if (EMPTYSTR(return_id->user_id)) {
    2.25          free(return_id->user_id);
    2.26 @@ -569,7 +576,7 @@
    2.27      }
    2.28      
    2.29      transfer_ident_lang_and_flags(return_id, stored_ident);
    2.30 -    
    2.31 +        
    2.32      if (return_id->comm_type == PEP_ct_unknown)
    2.33          return_id->comm_type = PEP_ct_key_not_found;
    2.34      
    2.35 @@ -1221,6 +1228,12 @@
    2.36          identity->comm_type = PEP_ct_unknown;
    2.37      }
    2.38      
    2.39 +    int major_ver = 0;
    2.40 +    int minor_ver = 0;
    2.41 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
    2.42 +    identity->major_ver = major_ver;
    2.43 +    identity->minor_ver = minor_ver;
    2.44 +    
    2.45      // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
    2.46      // it's NOT ok
    2.47      if (!read_only) {
     3.1 --- a/src/message.c	Wed Aug 07 11:55:15 2019 +0200
     3.2 +++ b/src/message.c	Wed Aug 07 12:00:56 2019 +0200
     3.3 @@ -44,6 +44,7 @@
     3.4          free_stringlist(msg->keywords);
     3.5          free(msg->comments);
     3.6          free_stringpair_list(msg->opt_fields);
     3.7 +        free(msg->_sender_fpr);
     3.8          free(msg);
     3.9      }
    3.10  }
    3.11 @@ -185,6 +186,12 @@
    3.12              goto enomem;
    3.13      }
    3.14  
    3.15 +    if (src->_sender_fpr) {
    3.16 +        msg->_sender_fpr = strdup(src->_sender_fpr);
    3.17 +        if (msg->_sender_fpr == NULL)
    3.18 +            goto enomem;
    3.19 +    }
    3.20 +    
    3.21      msg->enc_format = src->enc_format;
    3.22  
    3.23      return msg;
    3.24 @@ -218,13 +225,15 @@
    3.25      free(dst->longmsg);
    3.26      free(dst->longmsg_formatted);
    3.27      free(dst->comments);
    3.28 +    free(dst->_sender_fpr);
    3.29      dst->id = src->id;
    3.30      dst->shortmsg = src->shortmsg;
    3.31      dst->longmsg = src->longmsg;
    3.32      dst->longmsg_formatted = src->longmsg_formatted;
    3.33      dst->comments = src->comments;    
    3.34 +    dst->_sender_fpr = src->_sender_fpr;
    3.35      src->id = src->shortmsg = src->longmsg = src->longmsg_formatted = NULL;
    3.36 -    src->comments = NULL;
    3.37 +    src->comments = src->_sender_fpr = NULL;
    3.38      
    3.39      /* bloblists */
    3.40      free_bloblist(dst->attachments);
     4.1 --- a/src/message_api.c	Wed Aug 07 11:55:15 2019 +0200
     4.2 +++ b/src/message_api.c	Wed Aug 07 12:00:56 2019 +0200
     4.3 @@ -838,7 +838,7 @@
     4.4  }
     4.5  
     4.6  static message* wrap_message_as_attachment(message* envelope, 
     4.7 -    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
     4.8 +    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject, unsigned int max_major, unsigned int max_minor) {
     4.9      
    4.10      if (!attachment)
    4.11          return NULL;
    4.12 @@ -864,9 +864,17 @@
    4.13              default:
    4.14                  inner_type_string = "INNER";
    4.15          }
    4.16 -        attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);        
    4.17 -        _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    4.18 -
    4.19 +        if (max_major < 2 || (max_major == 2 && max_minor == 0)) {
    4.20 +            attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);        
    4.21 +            _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    4.22 +        }
    4.23 +        else {
    4.24 +            _envelope->longmsg = strdup(
    4.25 +                "This message was encrypted with p≡p (https://pep.software). If you are seeing this message,\n" 
    4.26 +                "your client does not support raising message attachments. Please click on the message attachment to\n"
    4.27 +                "to view it, or better yet, consider using p≡p!\n"
    4.28 +            );
    4.29 +        }
    4.30          // 2.1, to replace the above
    4.31          add_opt_field(attachment, X_PEP_MSG_WRAP_KEY, inner_type_string); 
    4.32      }
    4.33 @@ -1711,7 +1719,10 @@
    4.34      bool has_pEp_user = false;
    4.35      
    4.36      PEP_comm_type max_comm_type = PEP_ct_pEp;
    4.37 -
    4.38 +    unsigned int max_version_major = 0;
    4.39 +    unsigned int max_version_minor = 0;
    4.40 +    pEp_version_major_minor(PEP_VERSION, &max_version_major, &max_version_minor);
    4.41 +    
    4.42      identity_list * _il = NULL;
    4.43  
    4.44      if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
    4.45 @@ -1719,7 +1730,6 @@
    4.46      {
    4.47          //     - App splits mails with BCC in multiple mails.
    4.48          //     - Each email is encrypted separately
    4.49 -
    4.50          if(_il->next || (src->to && src->to->ident) || (src->cc && src->cc->ident))
    4.51          {
    4.52              // Only one Bcc with no other recipient allowed for now
    4.53 @@ -1733,6 +1743,12 @@
    4.54                  _il->ident->comm_type = PEP_ct_key_not_found;
    4.55                  _status = PEP_STATUS_OK;
    4.56              }
    4.57 +            // 0 unless set, so safe.
    4.58 +            
    4.59 +            set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
    4.60 +                             max_version_major, max_version_minor,
    4.61 +                             &max_version_major, &max_version_minor);
    4.62 +
    4.63              bool is_blacklisted = false;
    4.64              if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
    4.65                  _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
    4.66 @@ -1758,6 +1774,7 @@
    4.67          }
    4.68          else
    4.69              _status = myself(session, _il->ident);
    4.70 +        
    4.71          if (_status != PEP_STATUS_OK) {
    4.72              status = PEP_UNENCRYPTED;
    4.73              goto pEp_error;
    4.74 @@ -1785,6 +1802,11 @@
    4.75                      _il->ident->comm_type = PEP_ct_key_not_found;
    4.76                      _status = PEP_STATUS_OK;
    4.77                  }
    4.78 +                // 0 unless set, so safe.
    4.79 +                set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
    4.80 +                                 max_version_major, max_version_minor,
    4.81 +                                 &max_version_major, &max_version_minor);
    4.82 +                
    4.83                  bool is_blacklisted = false;
    4.84                  if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
    4.85                      _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
    4.86 @@ -1887,6 +1909,9 @@
    4.87              }
    4.88          }
    4.89      }
    4.90 +    
    4.91 +    if (max_version_major == 1)
    4.92 +        force_v_1 = true;
    4.93          
    4.94      if (enc_format == PEP_enc_none || !dest_keys_found ||
    4.95          stringlist_length(keys)  == 0 ||
    4.96 @@ -1906,7 +1931,7 @@
    4.97          message_wrap_type wrap_type = PEP_message_unwrapped;
    4.98          if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
    4.99              wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   4.100 -            _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
   4.101 +            _src = wrap_message_as_attachment(NULL, src, wrap_type, false, max_version_major, max_version_minor);
   4.102              if (!_src)
   4.103                  goto pEp_error;
   4.104          }
   4.105 @@ -2252,7 +2277,9 @@
   4.106      // if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   4.107      //     _attach_key(session, target_fpr, src);
   4.108  
   4.109 -    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
   4.110 +    unsigned int major_ver, minor_ver;
   4.111 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
   4.112 +    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false, major_ver, minor_ver);
   4.113      if (!_src)
   4.114          goto pEp_error;
   4.115  
   4.116 @@ -2981,11 +3008,28 @@
   4.117      return status;
   4.118  }
   4.119  
   4.120 +// ident is in_only and should have been updated
   4.121 +static PEP_STATUS pEp_version_upgrade_or_ignore(
   4.122 +        PEP_SESSION session,
   4.123 +        pEp_identity* ident,
   4.124 +        unsigned int major,
   4.125 +        unsigned int minor) {
   4.126 +            
   4.127 +    PEP_STATUS status = PEP_STATUS_OK;        
   4.128 +    int ver_compare = compare_versions(major, minor, ident->major_ver, ident->minor_ver);
   4.129 +    if (ver_compare > 0)
   4.130 +        status = set_pEp_version(session, ident, major, minor);        
   4.131 +    
   4.132 +    return status;    
   4.133 +}
   4.134 +
   4.135  // FIXME: myself ??????
   4.136  static PEP_STATUS update_sender_to_pEp_trust(
   4.137          PEP_SESSION session, 
   4.138          pEp_identity* sender, 
   4.139 -        stringlist_t* keylist) 
   4.140 +        stringlist_t* keylist,
   4.141 +        unsigned int major,
   4.142 +        unsigned int minor) 
   4.143  {
   4.144      assert(session);
   4.145      assert(sender);
   4.146 @@ -2996,9 +3040,11 @@
   4.147          
   4.148      free(sender->fpr);
   4.149      sender->fpr = NULL;
   4.150 -    
   4.151 -    PEP_STATUS status = 
   4.152 -            is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   4.153 +
   4.154 +    PEP_STATUS status = PEP_STATUS_OK;
   4.155 +
   4.156 +    // Seems status doesn't matter
   4.157 +    is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   4.158  
   4.159      if (EMPTYSTR(sender->fpr) || strcmp(sender->fpr, keylist->value) != 0) {
   4.160          free(sender->fpr);
   4.161 @@ -3023,11 +3069,21 @@
   4.162      
   4.163      // Could be done elegantly, but we do this explicitly here for readability.
   4.164      // This file's code is difficult enough to parse. But change at will.
   4.165 -    switch (sender->comm_type) {
   4.166 +    switch (sender->comm_type) {            
   4.167          case PEP_ct_OpenPGP_unconfirmed:
   4.168          case PEP_ct_OpenPGP:
   4.169              sender->comm_type = PEP_ct_pEp_unconfirmed | (sender->comm_type & PEP_ct_confirmed);
   4.170              status = set_trust(session, sender);
   4.171 +            if (status != PEP_STATUS_OK)
   4.172 +                break;
   4.173 +        case PEP_ct_pEp:
   4.174 +        case PEP_ct_pEp_unconfirmed:
   4.175 +            // set version
   4.176 +            if (major == 0) {
   4.177 +                major = 2;
   4.178 +                minor = 0;
   4.179 +            }
   4.180 +            status = pEp_version_upgrade_or_ignore(session, sender, major, minor);    
   4.181              break;
   4.182          default:
   4.183              status = PEP_CANNOT_SET_TRUST;
   4.184 @@ -3330,7 +3386,9 @@
   4.185      char* signer_fpr = NULL;
   4.186      bool is_pEp_msg = is_a_pEpmessage(src);
   4.187      bool myself_read_only = (src->dir == PEP_dir_incoming);
   4.188 -
   4.189 +    unsigned int major_ver;
   4.190 +    unsigned int minor_ver;
   4.191 +    
   4.192      // Grab input flags
   4.193      bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
   4.194      
   4.195 @@ -3346,34 +3404,39 @@
   4.196      *keylist = NULL;
   4.197      *rating = PEP_rating_undefined;
   4.198  //    *flags = 0;
   4.199 -    
   4.200 +
   4.201      /*** End init ***/
   4.202  
   4.203 -    // Ok, before we do anything, if it's a pEp message, regardless of whether it's
   4.204 +    // KB: FIXME - we should do this once we've seen an inner message in the case 
   4.205 +    // of pEp users. Since we've not used 1.0 in a billion years (but will receive 
   4.206 +    // 1.0 messages from pEp users who don't yet know WE are pEp users), we should 
   4.207 +    // sort this out sanely, not upfront.
   4.208 +    //
   4.209 +    // Was: Ok, before we do anything, if it's a pEp message, regardless of whether it's
   4.210      // encrypted or not, we set the sender as a pEp user. This has NOTHING to do
   4.211      // with the key.
   4.212 -    if (src->from && !(is_me(session, src->from))) {
   4.213 -        if (is_pEp_msg) {
   4.214 -            pEp_identity* tmp_from = src->from;
   4.215 -            
   4.216 -            // Ensure there's a user id
   4.217 -            if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   4.218 -                status = update_identity(session, tmp_from);
   4.219 -                if (status == PEP_CANNOT_FIND_IDENTITY) {
   4.220 -                    tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   4.221 -                    if (!tmp_from->user_id)
   4.222 -                        return PEP_OUT_OF_MEMORY;
   4.223 -                    snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   4.224 -                             "TOFU_%s", tmp_from->address);        
   4.225 -                    status = PEP_STATUS_OK;
   4.226 -                }
   4.227 -            }
   4.228 -            if (status == PEP_STATUS_OK) {
   4.229 -                // Now set user as PEP (may also create an identity if none existed yet)
   4.230 -                status = set_as_pEp_user(session, tmp_from);
   4.231 -            }
   4.232 -        }
   4.233 -    }
   4.234 +    // if (src->from && !(is_me(session, src->from))) {
   4.235 +    //     if (is_pEp_msg) {
   4.236 +    //         pEp_identity* tmp_from = src->from;
   4.237 +    // 
   4.238 +    //         // Ensure there's a user id
   4.239 +    //         if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   4.240 +    //             status = update_identity(session, tmp_from);
   4.241 +    //             if (status == PEP_CANNOT_FIND_IDENTITY) {
   4.242 +    //                 tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   4.243 +    //                 if (!tmp_from->user_id)
   4.244 +    //                     return PEP_OUT_OF_MEMORY;
   4.245 +    //                 snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   4.246 +    //                          "TOFU_%s", tmp_from->address);        
   4.247 +    //                 status = PEP_STATUS_OK;
   4.248 +    //             }
   4.249 +    //         }
   4.250 +    //         if (status == PEP_STATUS_OK) {
   4.251 +    //             // Now set user as PEP (may also create an identity if none existed yet)
   4.252 +    //             status = set_as_pEp_user(session, tmp_from);
   4.253 +    //         }
   4.254 +    //     }
   4.255 +    // }
   4.256      // We really need key used in signing to do anything further on the pEp comm_type.
   4.257      // So we can't adjust the rating of the sender just yet.
   4.258  
   4.259 @@ -3389,16 +3452,16 @@
   4.260      import_header_keys(session, src);
   4.261      
   4.262      // FIXME: is this really necessary here?
   4.263 -    if (src->from) {
   4.264 -        if (!is_me(session, src->from))
   4.265 -            status = update_identity(session, src->from);
   4.266 -        else
   4.267 -            status = _myself(session, src->from, false, false, myself_read_only);
   4.268 -        
   4.269 -        // We absolutely should NOT be bailing here unless it's a serious error
   4.270 -        if (status == PEP_OUT_OF_MEMORY)
   4.271 -            return status;
   4.272 -    }
   4.273 +    // if (src->from) {
   4.274 +    //     if (!is_me(session, src->from))
   4.275 +    //         status = update_identity(session, src->from);
   4.276 +    //     else
   4.277 +    //         status = _myself(session, src->from, false, false, myself_read_only);
   4.278 +    // 
   4.279 +    //     // We absolutely should NOT be bailing here unless it's a serious error
   4.280 +    //     if (status == PEP_OUT_OF_MEMORY)
   4.281 +    //         return status;
   4.282 +    // }
   4.283      
   4.284      /*** End Import any attached public keys and update identities accordingly ***/
   4.285      
   4.286 @@ -3598,6 +3661,8 @@
   4.287                          goto pEp_error;
   4.288                                  
   4.289                      if (inner_message) {
   4.290 +                        is_pEp_msg = is_a_pEpmessage(inner_message);
   4.291 +                        
   4.292                          // Though this will strip any message info on the
   4.293                          // attachment, this is safe, as we do not
   4.294                          // produce more than one attachment-as-message,
   4.295 @@ -3608,16 +3673,12 @@
   4.296  
   4.297                          const stringpair_list_t* pEp_protocol_version = NULL;
   4.298                          pEp_protocol_version = stringpair_list_find(inner_message->opt_fields, "X-pEp-Version");
   4.299 -                        unsigned int pEp_v_major = 0;
   4.300 -                        unsigned int pEp_v_minor = 0;
   4.301 -                        if (pEp_protocol_version && !EMPTYSTR(pEp_protocol_version->value->value)) {
   4.302 -                            // Roker is of course right. Meh :)
   4.303 -                            if (sscanf(pEp_protocol_version->value->value, "%u.%u", &pEp_v_major, &pEp_v_minor) != 2) {
   4.304 -                                pEp_v_major = 0;
   4.305 -                                pEp_v_minor = 0;
   4.306 -                            }
   4.307 -                        }
   4.308 -
   4.309 +                        
   4.310 +                        if (pEp_protocol_version && pEp_protocol_version->value)
   4.311 +                            pEp_version_major_minor(pEp_protocol_version->value->value, &major_ver, &minor_ver);
   4.312 +
   4.313 +                        // Sort out pEp user status and version number based on INNER message.
   4.314 +                        
   4.315                          bool is_inner = false;
   4.316                          bool is_key_reset = false;
   4.317  
   4.318 @@ -3629,20 +3690,22 @@
   4.319                          if (status != PEP_STATUS_OK)
   4.320                              goto pEp_error;                                         
   4.321                              
   4.322 -                        if (((pEp_v_major == 2) && (pEp_v_minor > 0)) || (pEp_v_major > 2)) {
   4.323 +                        if (major_ver > 2 || (major_ver == 2 && minor_ver > 0)) {
   4.324                              stringpair_list_t* searched = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");                             
   4.325                              inner_message->_sender_fpr = ((searched && searched->value && searched->value->value) ? strdup(searched->value->value) : NULL);
   4.326                              searched = stringpair_list_find(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   4.327                              if (searched && searched->value && searched->value->value) {
   4.328                                  is_inner = (strcmp(searched->value->value, "INNER") == 0);
   4.329                                  if (!is_inner)
   4.330 -                                    is_key_reset = (strcmp(searched->value->value, "INNER") == 0);
   4.331 +                                    is_key_reset = (strcmp(searched->value->value, "KEY_RESET") == 0);
   4.332 +                                if (is_inner || is_key_reset)
   4.333 +                                    inner_message->opt_fields = stringpair_list_delete_by_key(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   4.334                              }
   4.335                          }
   4.336                          else {
   4.337 -                                is_inner = (strcmp(wrap_info, "INNER") == 0);
   4.338 -                                if (!is_inner)
   4.339 -                                    is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   4.340 +                            is_inner = (strcmp(wrap_info, "INNER") == 0);
   4.341 +                            if (!is_inner)
   4.342 +                                is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   4.343                          }
   4.344                              
   4.345  
   4.346 @@ -3689,13 +3752,6 @@
   4.347                              //src = msg = inner_message;
   4.348                              calculated_src = msg = inner_message;
   4.349                              
   4.350 -                            // FIXME: should this be msg???
   4.351 -                            if (src->from) {
   4.352 -                                if (!is_me(session, src->from))
   4.353 -                                    update_identity(session, (src->from));
   4.354 -                                else
   4.355 -                                    _myself(session, src->from, false, false, myself_read_only);
   4.356 -                            }
   4.357                          }
   4.358                          else { // should never happen
   4.359                              status = PEP_UNKNOWN_ERROR;
   4.360 @@ -3716,14 +3772,35 @@
   4.361                  //  else {} // shouldn't be anything to be done here
   4.362      
   4.363              } // end if (has_inner || wrap_info)
   4.364 +            else {
   4.365 +                
   4.366 +            } // this we do if this isn't an inner message
   4.367 +            
   4.368 +            pEp_identity* cs_from = calculated_src->from;
   4.369 +            if (cs_from && !EMPTYSTR(cs_from->address)) {
   4.370 +                if (!is_me(session, cs_from)) {
   4.371 +                    status = update_identity(session, cs_from);
   4.372 +                    if (status == PEP_CANNOT_FIND_IDENTITY) {
   4.373 +                        cs_from->user_id = calloc(1, strlen(cs_from->address) + 6);
   4.374 +                        if (!cs_from->user_id)
   4.375 +                            return PEP_OUT_OF_MEMORY;
   4.376 +                        snprintf(cs_from->user_id, strlen(cs_from->address) + 6,
   4.377 +                                 "TOFU_%s", cs_from->address);        
   4.378 +                        status = PEP_STATUS_OK;
   4.379 +                    }
   4.380 +                }
   4.381 +                else
   4.382 +                    status = _myself(session, cs_from, false, false, myself_read_only);
   4.383 +            }                                                                        
   4.384          } // end if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   4.385          
   4.386          *rating = decrypt_rating(decrypt_status);
   4.387          
   4.388          // Ok, so if it was signed and it's all verified, we can update
   4.389          // eligible signer comm_types to PEP_ct_pEp_*
   4.390 +        // This also sets and upgrades pEp version
   4.391          if (decrypt_status == PEP_DECRYPTED_AND_VERIFIED && is_pEp_msg && calculated_src->from)
   4.392 -            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist);
   4.393 +            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist, major_ver, minor_ver);
   4.394  
   4.395          /* Ok, now we have a keylist used for decryption/verification.
   4.396             now we need to update the message rating with the 
   4.397 @@ -4095,7 +4172,7 @@
   4.398          *rating = PEP_rating_undefined;
   4.399      }
   4.400      else
   4.401 -        *rating = MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   4.402 +        *rating = _MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   4.403  
   4.404      return PEP_STATUS_OK;
   4.405  }
     5.1 --- a/src/mime.h	Wed Aug 07 11:55:15 2019 +0200
     5.2 +++ b/src/mime.h	Wed Aug 07 12:00:56 2019 +0200
     5.3 @@ -55,9 +55,10 @@
     5.4  // mime_decode_message() - decode a MIME message
     5.5  //
     5.6  //  parameters:
     5.7 -//      mimetext (in)           MIME encoded text to decode
     5.8 -//      size (in)               size of text to decode
     5.9 -//      msg (out)               decoded message
    5.10 +//      mimetext (in)           	MIME encoded text to decode
    5.11 +//      size (in)               	size of text to decode
    5.12 +//      msg (out)               	decoded message
    5.13 +//      raise_msg_attachment (out)		
    5.14  //
    5.15  //  return value:
    5.16  //      PEP_STATUS_OK           if everything worked
     6.1 --- a/src/pEpEngine.c	Wed Aug 07 11:55:15 2019 +0200
     6.2 +++ b/src/pEpEngine.c	Wed Aug 07 12:00:56 2019 +0200
     6.3 @@ -83,7 +83,7 @@
     6.4  static const char *sql_get_identity =  
     6.5      "select fpr, username, comm_type, lang,"
     6.6      "   identity.flags | pgp_keypair.flags,"
     6.7 -    "   is_own"
     6.8 +    "   is_own, pEp_version_major, pEp_version_minor"
     6.9      "   from identity"
    6.10      "   join person on id = identity.user_id"
    6.11      "   join pgp_keypair on fpr = identity.main_key_id"
    6.12 @@ -101,7 +101,7 @@
    6.13  static const char *sql_get_identities_by_main_key_id =  
    6.14      "select address, identity.user_id, username, comm_type, lang,"
    6.15      "   identity.flags | pgp_keypair.flags,"
    6.16 -    "   is_own"
    6.17 +    "   is_own, pEp_version_major, pEp_version_minor"
    6.18      "   from identity"
    6.19      "   join person on id = identity.user_id"
    6.20      "   join pgp_keypair on fpr = identity.main_key_id"
    6.21 @@ -113,7 +113,7 @@
    6.22  
    6.23  static const char *sql_get_identity_without_trust_check =  
    6.24      "select identity.main_key_id, username, lang,"
    6.25 -    "   identity.flags, is_own"
    6.26 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
    6.27      "   from identity"
    6.28      "   join person on id = identity.user_id"
    6.29      "   where (case when (address = ?1) then (1)"
    6.30 @@ -127,7 +127,7 @@
    6.31  
    6.32  static const char *sql_get_identities_by_address =  
    6.33      "select user_id, identity.main_key_id, username, lang,"
    6.34 -    "   identity.flags, is_own"
    6.35 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
    6.36      "   from identity"
    6.37      "   join person on id = identity.user_id"
    6.38      "   where (case when (address = ?1) then (1)"
    6.39 @@ -141,7 +141,7 @@
    6.40  static const char *sql_get_identities_by_userid =  
    6.41      "select address, fpr, username, comm_type, lang,"
    6.42      "   identity.flags | pgp_keypair.flags,"
    6.43 -    "   is_own"
    6.44 +    "   is_own, pEp_version_major, pEp_version_minor"
    6.45      "   from identity"
    6.46      "   join person on id = identity.user_id"
    6.47      "   join pgp_keypair on fpr = identity.main_key_id"
    6.48 @@ -239,20 +239,25 @@
    6.49  static const char *sql_set_identity_entry = 
    6.50      "insert into identity ("
    6.51      "       address, main_key_id, "
    6.52 -    "       user_id, flags, is_own"
    6.53 +    "       user_id, flags, is_own,"
    6.54 +    "       pEp_version_major, pEp_version_minor"
    6.55      "   ) values ("
    6.56      "       ?1,"
    6.57      "       upper(replace(?2,' ','')),"
    6.58      "       ?3,"
    6.59      "       ?4,"
    6.60 -    "       ?5"
    6.61 +    "       ?5,"
    6.62 +    "       ?6,"
    6.63 +    "       ?7"
    6.64      "   );";
    6.65      
    6.66  static const char* sql_update_identity_entry =    
    6.67      "update identity "
    6.68      "   set main_key_id = upper(replace(?2,' ','')), "
    6.69      "       flags = ?4, " 
    6.70 -    "       is_own = ?5 "
    6.71 +    "       is_own = ?5, "
    6.72 +    "       pEp_version_major = ?6, "
    6.73 +    "       pEp_version_major = ?7 "    
    6.74      "   where (case when (address = ?1) then (1)"
    6.75      "               when (lower(address) = lower(?1)) then (1)"
    6.76      "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
    6.77 @@ -301,6 +306,28 @@
    6.78      "          end) = 1"
    6.79      "          and user_id = ?3 ;";
    6.80  
    6.81 +static const char *sql_set_pEp_version =
    6.82 +    "update identity "
    6.83 +    "   set pEp_version_major = ?1, "
    6.84 +    "       pEp_version_minor = ?2 "
    6.85 +    "   where (case when (address = ?3) then (1)"
    6.86 +    "               when (lower(address) = lower(?3)) then (1)"
    6.87 +    "               when (replace(lower(address),'.','') = replace(lower(?3),'.','')) then (1) "
    6.88 +    "               else 0 "
    6.89 +    "          end) = 1 "
    6.90 +    "          and user_id = ?4 ;";
    6.91 +
    6.92 +static const char *sql_upgrade_pEp_version_by_user_id =
    6.93 +    "update identity "
    6.94 +    "   set pEp_version_major = ?1, "
    6.95 +    "       pEp_version_minor = ?2 "
    6.96 +    "       where user_id = ?3 "
    6.97 +    "           and (case when (pEp_version_major < ?1) then (1)"
    6.98 +    "                     when (pEp_version_major > ?1) then (0)"
    6.99 +    "                     when (pEp_version_minor < ?2) then (1)"
   6.100 +    "                     else 0 "
   6.101 +    "           end) = 1 ;";
   6.102 +
   6.103  static const char *sql_set_trust =
   6.104      "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   6.105      "values (?1, upper(replace(?2,' ','')), ?3) ;";
   6.106 @@ -353,7 +380,7 @@
   6.107  
   6.108  static const char *sql_i18n_token = 
   6.109      "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   6.110 -
   6.111 +    
   6.112  // blacklist
   6.113  static const char *sql_blacklist_add = 
   6.114      "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   6.115 @@ -393,7 +420,7 @@
   6.116  
   6.117  static const char *sql_own_identities_retrieve =  
   6.118      "select address, fpr, identity.user_id, username,"
   6.119 -    "   lang, identity.flags | pgp_keypair.flags"
   6.120 +    "   lang, identity.flags | pgp_keypair.flags, pEp_version_major, pEp_version_minor"
   6.121      "   from identity"
   6.122      "   join person on id = identity.user_id"
   6.123      "   join pgp_keypair on fpr = identity.main_key_id"
   6.124 @@ -965,6 +992,8 @@
   6.125                  "   comment text,\n"
   6.126                  "   flags integer default 0,\n"
   6.127                  "   is_own integer default 0,\n"
   6.128 +                "   pEp_version_major integer default 0,\n"
   6.129 +                "   pEp_version_minor integer default 0,\n"                
   6.130                  "   timestamp integer default (datetime('now')),\n"
   6.131                  "   primary key (address, user_id)\n"
   6.132                  ");\n"
   6.133 @@ -1071,7 +1100,10 @@
   6.134          // Sometimes the user_version wasn't set correctly. 
   6.135          if (version == 1) {
   6.136              bool version_changed = true;
   6.137 -            if (db_contains_table(_session, "social_graph") > 0) {
   6.138 +            if (table_contains_column(_session, "identity", "pEp_version_major")) {
   6.139 +                version = 12;
   6.140 +            }
   6.141 +            else if (db_contains_table(_session, "social_graph") > 0) {
   6.142                  if (!table_contains_column(_session, "person", "device_group"))
   6.143                      version = 10;
   6.144                  else
   6.145 @@ -1433,7 +1465,71 @@
   6.146                      NULL,
   6.147                      NULL
   6.148                  );
   6.149 -                assert(int_result == SQLITE_OK);                
   6.150 +                assert(int_result == SQLITE_OK);
   6.151 +                
   6.152 +                int_result = sqlite3_exec(
   6.153 +                    _session->db,
   6.154 +                    "alter table identity\n"
   6.155 +                    "   add column pEp_version_major integer default 0;\n"
   6.156 +                    "alter table identity\n"
   6.157 +                    "   add column pEp_version_minor integer default 0;\n",                    
   6.158 +                    NULL,
   6.159 +                    NULL,
   6.160 +                    NULL
   6.161 +                );
   6.162 +                if (status != PEP_STATUS_OK)
   6.163 +                    return status;  
   6.164 +      
   6.165 +                int_result = sqlite3_exec(
   6.166 +                    _session->db,
   6.167 +                    "update identity\n"
   6.168 +                    "   set pEp_version_major = 2\n"
   6.169 +                    "   where exists (select * from person\n"
   6.170 +                    "                     where identity.user_id = person.id\n"
   6.171 +                    "                     and identity.is_own = 0\n"
   6.172 +                    "                     and person.is_pEp_user = 1);\n",
   6.173 +                    NULL,
   6.174 +                    NULL,
   6.175 +                    NULL
   6.176 +                );
   6.177 +                if (status != PEP_STATUS_OK)
   6.178 +                    return status;  
   6.179 +                
   6.180 +                // N.B. WE DEFINE PEP_VERSION - IF WE'RE AT 9-DIGIT MAJOR OR MINOR VERSIONS, ER, BAD.
   6.181 +                char major_buf[10];
   6.182 +                char minor_buf[10];
   6.183 +                if (sscanf("%s.%s", major_buf, minor_buf) != 2)
   6.184 +                    return PEP_UNKNOWN_ERROR; // DO BETTER
   6.185 +                size_t major_len = strlen(major_buf);
   6.186 +                size_t minor_len = strlen(minor_buf);
   6.187 +                    
   6.188 +                const char* _ver_12_startstr =                     
   6.189 +                    "update identity\n"
   6.190 +                    "    set pEp_version_major = ";
   6.191 +                const char* _ver_12_midstr = ",\n"
   6.192 +                    "        pEp_version_minor = ";
   6.193 +                const char* _ver_12_endstr =     
   6.194 +                    "\n"
   6.195 +                    "    where identity.is_own = 1;\n";
   6.196 +                    
   6.197 +                size_t new_stringlen = strlen(_ver_12_startstr) + major_len +
   6.198 +                                       strlen(_ver_12_midstr) + minor_len +
   6.199 +                                       strlen(_ver_12_endstr);
   6.200 +                                       
   6.201 +                char* _ver_12_stmt = calloc(new_stringlen + 1, 1);
   6.202 +                snprintf(_ver_12_stmt, new_stringlen + 1, "%s%s%s%s%s",
   6.203 +                         _ver_12_startstr, major_buf, _ver_12_midstr, minor_buf, _ver_12_endstr);
   6.204 +                
   6.205 +                int_result = sqlite3_exec(
   6.206 +                    _session->db,
   6.207 +                    _ver_12_stmt,
   6.208 +                    NULL,
   6.209 +                    NULL,
   6.210 +                    NULL
   6.211 +                );
   6.212 +                free(_ver_12_stmt);
   6.213 +                if (status != PEP_STATUS_OK)
   6.214 +                    return status;                      
   6.215              }
   6.216          }        
   6.217          else { 
   6.218 @@ -1633,6 +1729,16 @@
   6.219              NULL);
   6.220      assert(int_result == SQLITE_OK);
   6.221  
   6.222 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_pEp_version,
   6.223 +            (int)strlen(sql_set_pEp_version), &_session->set_pEp_version,
   6.224 +            NULL);
   6.225 +    assert(int_result == SQLITE_OK);
   6.226 +    
   6.227 +    int_result = sqlite3_prepare_v2(_session->db, sql_upgrade_pEp_version_by_user_id,
   6.228 +            (int)strlen(sql_upgrade_pEp_version_by_user_id), &_session->upgrade_pEp_version_by_user_id,
   6.229 +            NULL);
   6.230 +    assert(int_result == SQLITE_OK);
   6.231 +
   6.232      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
   6.233              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
   6.234      assert(int_result == SQLITE_OK);
   6.235 @@ -1873,6 +1979,8 @@
   6.236                  sqlite3_finalize(session->delete_person);                
   6.237              if (session->set_as_pEp_user)
   6.238                  sqlite3_finalize(session->set_as_pEp_user);
   6.239 +            if (session->upgrade_pEp_version_by_user_id)
   6.240 +                sqlite3_finalize(session->upgrade_pEp_version_by_user_id);
   6.241              if (session->is_pEp_user)
   6.242                  sqlite3_finalize(session->is_pEp_user);
   6.243              if (session->exists_person)
   6.244 @@ -1901,6 +2009,8 @@
   6.245                  sqlite3_finalize(session->set_identity_flags);
   6.246              if (session->unset_identity_flags)
   6.247                  sqlite3_finalize(session->unset_identity_flags);
   6.248 +            if (session->set_pEp_version)
   6.249 +                sqlite3_finalize(session->set_pEp_version);                
   6.250              if (session->exists_trust_entry)
   6.251                  sqlite3_finalize(session->exists_trust_entry);                                
   6.252              if (session->set_trust)
   6.253 @@ -2269,6 +2379,8 @@
   6.254      dup->lang[2] = 0;
   6.255      dup->flags = src->flags;
   6.256      dup->me = src->me;
   6.257 +    dup->major_ver = src->major_ver;
   6.258 +    dup->minor_ver = src->minor_ver;
   6.259      
   6.260      return dup;
   6.261  }
   6.262 @@ -2462,6 +2574,10 @@
   6.263              sqlite3_column_int(session->get_identity, 4);
   6.264          _identity->me = (unsigned int)
   6.265              sqlite3_column_int(session->get_identity, 5);
   6.266 +        _identity->major_ver =
   6.267 +            sqlite3_column_int(session->get_identity, 6);
   6.268 +        _identity->minor_ver =
   6.269 +            sqlite3_column_int(session->get_identity, 7);
   6.270      
   6.271          *identity = _identity;
   6.272          break;
   6.273 @@ -2536,6 +2652,10 @@
   6.274              sqlite3_column_int(session->get_identities_by_userid, 5);
   6.275          ident->me = (unsigned int)
   6.276              sqlite3_column_int(session->get_identities_by_userid, 6);
   6.277 +        ident->major_ver =
   6.278 +            sqlite3_column_int(session->get_identities_by_userid, 7);
   6.279 +        ident->minor_ver =
   6.280 +            sqlite3_column_int(session->get_identities_by_userid, 8);
   6.281      
   6.282          identity_list_add(*identities, ident);
   6.283          ident = NULL;
   6.284 @@ -2602,6 +2722,10 @@
   6.285              sqlite3_column_int(session->get_identities_by_main_key_id, 5);
   6.286          ident->me = (unsigned int)
   6.287              sqlite3_column_int(session->get_identities_by_main_key_id, 6);
   6.288 +        ident->major_ver =
   6.289 +            sqlite3_column_int(session->get_identities_by_main_key_id, 7);
   6.290 +        ident->minor_ver =
   6.291 +            sqlite3_column_int(session->get_identities_by_main_key_id, 8);
   6.292      
   6.293          identity_list_add(*identities, ident);
   6.294          ident = NULL;
   6.295 @@ -2672,6 +2796,10 @@
   6.296              sqlite3_column_int(session->get_identity_without_trust_check, 3);
   6.297          _identity->me = (unsigned int)
   6.298              sqlite3_column_int(session->get_identity_without_trust_check, 4);
   6.299 +        _identity->major_ver =
   6.300 +            sqlite3_column_int(session->get_identity_without_trust_check, 5);
   6.301 +        _identity->minor_ver =
   6.302 +            sqlite3_column_int(session->get_identity_without_trust_check, 6);
   6.303      
   6.304          *identity = _identity;
   6.305          break;
   6.306 @@ -2737,6 +2865,10 @@
   6.307              sqlite3_column_int(session->get_identities_by_address, 4);
   6.308          ident->me = (unsigned int)
   6.309              sqlite3_column_int(session->get_identities_by_address, 5);
   6.310 +        ident->major_ver =
   6.311 +            sqlite3_column_int(session->get_identities_by_address, 6);
   6.312 +        ident->minor_ver =
   6.313 +            sqlite3_column_int(session->get_identities_by_address, 7);
   6.314      
   6.315          if (ident_list)
   6.316              identity_list_add(ident_list, ident);
   6.317 @@ -2893,6 +3025,9 @@
   6.318              SQLITE_STATIC);
   6.319      sqlite3_bind_int(set_or_update, 4, identity->flags);
   6.320      sqlite3_bind_int(set_or_update, 5, identity->me);
   6.321 +    sqlite3_bind_int(set_or_update, 6, identity->major_ver);
   6.322 +    sqlite3_bind_int(set_or_update, 7, identity->minor_ver);
   6.323 +        
   6.324      int result = Sqlite3_step(set_or_update);
   6.325      sqlite3_reset(set_or_update);
   6.326      if (result != SQLITE_DONE)
   6.327 @@ -3006,7 +3141,7 @@
   6.328                                         guard_transaction);
   6.329  }
   6.330  
   6.331 -// This will NOT call set_as_pEp_user; you have to do that separately.
   6.332 +// This will NOT call set_as_pEp_user, nor set_pEp_version; you have to do that separately.
   6.333  DYNAMIC_API PEP_STATUS set_identity(
   6.334          PEP_SESSION session, const pEp_identity *identity
   6.335      )
   6.336 @@ -3073,6 +3208,12 @@
   6.337          }
   6.338      }
   6.339      
   6.340 +    status = set_pEp_version(session, ident_copy, ident_copy->major_ver, ident_copy->minor_ver);
   6.341 +    if (status != PEP_STATUS_OK) {
   6.342 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   6.343 +        goto pEp_free;            
   6.344 +    }
   6.345 +    
   6.346      result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
   6.347      if (result == SQLITE_OK)
   6.348          status = PEP_STATUS_OK;
   6.349 @@ -3097,7 +3238,9 @@
   6.350      if (result != SQLITE_DONE)
   6.351          return PEP_CANNOT_SET_TRUST;
   6.352  
   6.353 -    return PEP_STATUS_OK;
   6.354 +    PEP_STATUS status = upgrade_pEp_version_by_user_id(session, user, 2, 0);
   6.355 +    
   6.356 +    return status;
   6.357  }
   6.358  
   6.359  
   6.360 @@ -3138,6 +3281,54 @@
   6.361      return status;
   6.362  }
   6.363  
   6.364 +// This ONLY sets the version flag. Must be called outside of a transaction.
   6.365 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor) {
   6.366 +    assert(session);
   6.367 +    assert(!EMPTYSTR(ident->user_id));
   6.368 +    assert(!EMPTYSTR(ident->address));
   6.369 +    
   6.370 +    sqlite3_reset(session->set_pEp_version);
   6.371 +    sqlite3_bind_double(session->set_pEp_version, 1, new_ver_major);
   6.372 +    sqlite3_bind_double(session->set_pEp_version, 2, new_ver_minor);    
   6.373 +    sqlite3_bind_text(session->set_pEp_version, 3, ident->address, -1,
   6.374 +            SQLITE_STATIC);
   6.375 +    sqlite3_bind_text(session->set_pEp_version, 4, ident->user_id, -1,
   6.376 +            SQLITE_STATIC);
   6.377 +    
   6.378 +    int result = Sqlite3_step(session->set_pEp_version);
   6.379 +    sqlite3_reset(session->set_pEp_version);
   6.380 +        
   6.381 +    if (result != SQLITE_DONE)
   6.382 +        return PEP_CANNOT_SET_PEP_VERSION;
   6.383 +    
   6.384 +    return PEP_STATUS_OK;
   6.385 +}
   6.386 +
   6.387 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
   6.388 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
   6.389 +        pEp_identity* ident, 
   6.390 +        unsigned int new_ver_major,
   6.391 +        unsigned int new_ver_minor
   6.392 +    ) 
   6.393 +{
   6.394 +    assert(session);
   6.395 +    assert(!EMPTYSTR(ident->user_id));
   6.396 +    
   6.397 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
   6.398 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 1, new_ver_major);
   6.399 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 2, new_ver_minor);    
   6.400 +    sqlite3_bind_text(session->upgrade_pEp_version_by_user_id, 3, ident->user_id, -1,
   6.401 +            SQLITE_STATIC);
   6.402 +    
   6.403 +    int result = Sqlite3_step(session->upgrade_pEp_version_by_user_id);
   6.404 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
   6.405 +        
   6.406 +    if (result != SQLITE_DONE)
   6.407 +        return PEP_CANNOT_SET_PEP_VERSION;
   6.408 +    
   6.409 +    return PEP_STATUS_OK;    
   6.410 +}
   6.411 +
   6.412  PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
   6.413                           bool* exists) {            
   6.414      
     7.1 --- a/src/pEpEngine.h	Wed Aug 07 11:55:15 2019 +0200
     7.2 +++ b/src/pEpEngine.h	Wed Aug 07 12:00:56 2019 +0200
     7.3 @@ -69,6 +69,7 @@
     7.4      PEP_CANNOT_SET_TRUST                            = 0x0384,
     7.5      PEP_KEY_BLACKLISTED                             = 0x0385,
     7.6      PEP_CANNOT_FIND_PERSON                          = 0x0386,
     7.7 +    PEP_CANNOT_SET_PEP_VERSION                      = 0X0387,
     7.8      
     7.9      PEP_CANNOT_FIND_ALIAS                           = 0x0391,
    7.10      PEP_CANNOT_SET_ALIAS                            = 0x0392,
    7.11 @@ -597,6 +598,8 @@
    7.12      char lang[3];               // language of conversation
    7.13                                  // ISO 639-1 ALPHA-2, last byte is 0
    7.14      bool me;                    // if this is the local user herself/himself
    7.15 +    int major_ver;              // highest version of pEp message received, if any
    7.16 +    int minor_ver;              // highest version of pEp message received, if any
    7.17      identity_flags_t flags;     // identity_flag1 | identity_flag2 | ...
    7.18  } pEp_identity;
    7.19  
    7.20 @@ -1354,6 +1357,15 @@
    7.21  
    7.22  PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr);
    7.23  
    7.24 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor);
    7.25 +
    7.26 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
    7.27 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
    7.28 +        pEp_identity* ident, 
    7.29 +        unsigned int new_ver_major,
    7.30 +        unsigned int new_ver_minor
    7.31 +    );
    7.32 +     
    7.33  // exposed for testing
    7.34  PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
    7.35                        bool guard_transaction);
     8.1 --- a/src/pEp_internal.h	Wed Aug 07 11:55:15 2019 +0200
     8.2 +++ b/src/pEp_internal.h	Wed Aug 07 12:00:56 2019 +0200
     8.3 @@ -182,6 +182,7 @@
     8.4      sqlite3_stmt *exists_person;    
     8.5      sqlite3_stmt *set_as_pEp_user;
     8.6      sqlite3_stmt *is_pEp_user;
     8.7 +    sqlite3_stmt *upgrade_pEp_version_by_user_id;
     8.8      sqlite3_stmt *add_into_social_graph;
     8.9      sqlite3_stmt *get_own_address_binding_from_contact;
    8.10      sqlite3_stmt *set_revoke_contact_as_notified;
    8.11 @@ -196,6 +197,7 @@
    8.12      sqlite3_stmt *exists_identity_entry;        
    8.13      sqlite3_stmt *set_identity_flags;
    8.14      sqlite3_stmt *unset_identity_flags;
    8.15 +    sqlite3_stmt *set_pEp_version;    
    8.16      sqlite3_stmt *set_trust;
    8.17      sqlite3_stmt *update_trust;
    8.18      sqlite3_stmt *exists_trust_entry;
    8.19 @@ -456,6 +458,68 @@
    8.20      return retval;
    8.21  }
    8.22  
    8.23 +static inline float pEp_version_numeric(const char* version_str) {
    8.24 +    float retval = 0;    
    8.25 +        
    8.26 +    if (!version_str || sscanf(version_str, "%f", &retval) != 1)
    8.27 +        return 0;
    8.28 +        
    8.29 +    return retval;    
    8.30 +}
    8.31 +
    8.32 +static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
    8.33 +    if (!major || !minor)
    8.34 +        return;
    8.35 +                
    8.36 +    if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
    8.37 +        *major = 0;
    8.38 +        *minor = 0;
    8.39 +    }
    8.40 +        
    8.41 +    return;    
    8.42 +}
    8.43 +
    8.44 +static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
    8.45 +                                   unsigned int second_maj, unsigned int second_min) {
    8.46 +    if (first_maj > second_maj)
    8.47 +        return 1;
    8.48 +    if (first_maj < second_maj)
    8.49 +        return -1;
    8.50 +    if (first_min > second_min)
    8.51 +        return 1;
    8.52 +    if (first_min < second_min)
    8.53 +        return -1;
    8.54 +    return 0;    
    8.55 +}
    8.56 +
    8.57 +static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
    8.58 +                                   unsigned int second_maj, unsigned int second_minor,
    8.59 +                                   unsigned int* result_maj, unsigned int* result_minor) {
    8.60 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
    8.61 +    if (result < 0) {
    8.62 +        *result_maj = first_maj;
    8.63 +        *result_minor = first_minor;
    8.64 +    }
    8.65 +    else {
    8.66 +        *result_maj = second_maj;
    8.67 +        *result_minor = second_minor;
    8.68 +    }    
    8.69 +}
    8.70 +
    8.71 +static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
    8.72 +                                   unsigned int second_maj, unsigned int second_minor,
    8.73 +                                   unsigned int* result_maj, unsigned int* result_minor) {
    8.74 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
    8.75 +    if (result > 0) {
    8.76 +        *result_maj = first_maj;
    8.77 +        *result_minor = first_minor;
    8.78 +    }
    8.79 +    else {
    8.80 +        *result_maj = second_maj;
    8.81 +        *result_minor = second_minor;
    8.82 +    }    
    8.83 +}
    8.84 +
    8.85  #ifndef EMPTYSTR
    8.86  #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
    8.87  #endif
    8.88 @@ -471,7 +535,6 @@
    8.89  #define _MAX(A, B) ((B) > (A) ? (B) : (A))
    8.90  #endif
    8.91  
    8.92 -
    8.93  // These are globals used in generating message IDs and should only be
    8.94  // computed once, as they're either really constants or OS-dependent
    8.95  
     9.1 --- a/src/stringpair.c	Wed Aug 07 11:55:15 2019 +0200
     9.2 +++ b/src/stringpair.c	Wed Aug 07 12:00:56 2019 +0200
     9.3 @@ -194,6 +194,41 @@
     9.4      }
     9.5  }
     9.6  
     9.7 +// ONLY DELETES ONE.
     9.8 +DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
     9.9 +        stringpair_list_t *sp_list,
    9.10 +        const char *key
    9.11 +    )
    9.12 +{
    9.13 +    assert(sp_list);
    9.14 +    assert(key);
    9.15 +
    9.16 +    if (sp_list->value == NULL) {
    9.17 +        free_stringpair_list(sp_list);
    9.18 +        return NULL;
    9.19 +    }
    9.20 +
    9.21 +    if (key == NULL)
    9.22 +        return sp_list;
    9.23 +
    9.24 +    stringpair_list_t *_sl;
    9.25 +    stringpair_list_t *last = NULL;
    9.26 +    for (_sl = sp_list; _sl && _sl->value && _sl->value->key; _sl = _sl->next) {
    9.27 +        if (strcmp(_sl->value->key, key) == 0) {
    9.28 +            if (last == NULL)
    9.29 +                sp_list = sp_list->next;
    9.30 +            else
    9.31 +                last->next = _sl->next;
    9.32 +            _sl->next = NULL;
    9.33 +            free_stringpair_list(_sl);
    9.34 +            break;
    9.35 +        }
    9.36 +        last = _sl;
    9.37 +    }
    9.38 +    return sp_list;
    9.39 +}
    9.40 +
    9.41 +
    9.42  DYNAMIC_API stringpair_list_t *stringpair_list_find(
    9.43          stringpair_list_t *stringpair_list,
    9.44          const char *key
    10.1 --- a/src/stringpair.h	Wed Aug 07 11:55:15 2019 +0200
    10.2 +++ b/src/stringpair.h	Wed Aug 07 12:00:56 2019 +0200
    10.3 @@ -159,8 +159,13 @@
    10.4          const char *key
    10.5      );
    10.6  
    10.7 +// ONLY DELETES ONE.
    10.8 +DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
    10.9 +        stringpair_list_t *sp_list,
   10.10 +        const char *key
   10.11 +    );
   10.12 +
   10.13  
   10.14  #ifdef __cplusplus
   10.15  }
   10.16  #endif
   10.17 -
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.cc	Wed Aug 07 12:00:56 2019 +0200
    11.3 @@ -0,0 +1,80 @@
    11.4 +// This file is under GNU General Public License 3.0
    11.5 +// see LICENSE.txt
    11.6 +
    11.7 +#include <stdlib.h>
    11.8 +#include <cstring>
    11.9 +#include <string>
   11.10 +#include <fstream>
   11.11 +#include <iostream>
   11.12 +
   11.13 +#include <cpptest.h>
   11.14 +#include "test_util.h"
   11.15 +
   11.16 +#include "pEpEngine.h"
   11.17 +
   11.18 +#include "EngineTestIndividualSuite.h"
   11.19 +#include "ExportKeyUtilTests.h"
   11.20 +
   11.21 +using namespace std;
   11.22 +
   11.23 +ExportKeyUtilTests::ExportKeyUtilTests(string suitename, string test_home_dir) :
   11.24 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   11.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("ExportKeyUtilTests::check_export_key_util"),
   11.26 +                                                                      static_cast<Func>(&ExportKeyUtilTests::check_export_key_util)));
   11.27 +}
   11.28 +
   11.29 +void ExportKeyUtilTests::setup() {
   11.30 +    string key_db_name;
   11.31 +    cout << "Please indicate the name of the key DB file: ";
   11.32 +    cin >> key_db_name;
   11.33 +    add_file_to_home_dir_queue(key_db_name, ".pEp_keys.db");
   11.34 +    EngineTestIndividualSuite::setup();
   11.35 +}
   11.36 +
   11.37 +void ExportKeyUtilTests::check_export_key_util() {
   11.38 +    string search_term;
   11.39 +    string output_file;
   11.40 +    cout << "Please give address (containing @) or key_id to dump: ";
   11.41 +    cin >> search_term;
   11.42 +    stringlist_t* keylist = NULL;
   11.43 +    PEP_STATUS status = find_keys(session, search_term.c_str(), &keylist);
   11.44 +    TEST_ASSERT(status == PEP_STATUS_OK);
   11.45 +    TEST_ASSERT(keylist);
   11.46 +    string priv;
   11.47 +    cout << "Private keys? (y/N)";
   11.48 +    cin >> priv;
   11.49 +    string outdir;
   11.50 +    cout << "Output directory? (curdir is default)";
   11.51 +    cin >> outdir;
   11.52 +    stringlist_t* curr = keylist;
   11.53 +    while (curr) {
   11.54 +        string fpr = curr->value;
   11.55 +        if (!fpr.empty()) {
   11.56 +            char* key = NULL;
   11.57 +            size_t size = 0;
   11.58 +            status = export_key(session, fpr.c_str(), &key, &size);
   11.59 +            if (key && size != 0) {
   11.60 +                ofstream outfile;
   11.61 +                outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   11.62 +                outfile.write(key, size);
   11.63 +                outfile.close();
   11.64 +            }
   11.65 +            free(key);
   11.66 +            size = 0;
   11.67 +            key = NULL;
   11.68 +            if (priv.c_str()[0] == 'y' || priv.c_str()[0] == 'Y') {
   11.69 +                status = export_secret_key(session, fpr.c_str(), &key, &size);
   11.70 +                if (key && size != 0) {
   11.71 +                    ofstream outfile;
   11.72 +                    outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   11.73 +                    outfile.write(key, size);
   11.74 +                    outfile.close();                    
   11.75 +                }                
   11.76 +            }   
   11.77 +            free(key);
   11.78 +        }
   11.79 +        curr = curr->next;
   11.80 +    }
   11.81 +    
   11.82 +    TEST_ASSERT(true);
   11.83 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.h	Wed Aug 07 12:00:56 2019 +0200
    12.3 @@ -0,0 +1,21 @@
    12.4 +// This file is under GNU General Public License 3.0
    12.5 +// see LICENSE.txt
    12.6 +
    12.7 +#ifndef EXPORT_KEY_UTIL_H
    12.8 +#define EXPORT_KEY_UTIL_H
    12.9 +
   12.10 +#include <string>
   12.11 +#include "EngineTestIndividualSuite.h"
   12.12 +
   12.13 +using namespace std;
   12.14 +
   12.15 +class ExportKeyUtilTests : public EngineTestIndividualSuite {
   12.16 +    public:
   12.17 +        ExportKeyUtilTests(string test_suite, string test_home_dir);
   12.18 +    protected:
   12.19 +        void setup();    
   12.20 +    private:
   12.21 +        void check_export_key_util();
   12.22 +};
   12.23 +
   12.24 +#endif
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/include/GetKeyRatingForUserTests.h	Wed Aug 07 12:00:56 2019 +0200
    13.3 @@ -0,0 +1,19 @@
    13.4 +// This file is under GNU General Public License 3.0
    13.5 +// see LICENSE.txt
    13.6 +
    13.7 +#ifndef GET_KEY_RATING_FOR_USER_H
    13.8 +#define GET_KEY_RATING_FOR_USER_H
    13.9 +
   13.10 +#include <string>
   13.11 +#include "EngineTestIndividualSuite.h"
   13.12 +
   13.13 +using namespace std;
   13.14 +
   13.15 +class GetKeyRatingForUserTests : public EngineTestIndividualSuite {
   13.16 +    public:
   13.17 +        GetKeyRatingForUserTests(string test_suite, string test_home_dir);
   13.18 +    private:
   13.19 +        void check_get_key_rating_for_user();
   13.20 +};
   13.21 +
   13.22 +#endif
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/include/Message2_1Tests.h	Wed Aug 07 12:00:56 2019 +0200
    14.3 @@ -0,0 +1,28 @@
    14.4 +// This file is under GNU General Public License 3.0
    14.5 +// see LICENSE.txt
    14.6 +
    14.7 +#ifndef MESSAGE2_1_H
    14.8 +#define MESSAGE2_1_H
    14.9 +
   14.10 +#include <string>
   14.11 +#include "EngineTestIndividualSuite.h"
   14.12 +
   14.13 +using namespace std;
   14.14 +
   14.15 +class Message2_1Tests : public EngineTestIndividualSuite {
   14.16 +    public:
   14.17 +        Message2_1Tests(string test_suite, string test_home_dir);
   14.18 +    private:
   14.19 +        bool verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout);
   14.20 +        
   14.21 +        void check_message2_1_recip_2_0();
   14.22 +        void check_message2_1_recip_OpenPGP();
   14.23 +        void check_message2_1_recip_2_1();
   14.24 +        void check_message2_1_recip_1_0_from_msg_OpenPGP();
   14.25 +        void check_message2_1_recip_2_0_from_msg();
   14.26 +        void check_message2_1_recip_2_1_from_msg();
   14.27 +        void check_message2_1_recip_mixed_2_0();
   14.28 +        void check_message2_1_recip_mixed_1_0_OpenPGP();
   14.29 +};
   14.30 +
   14.31 +#endif
    15.1 --- a/test/include/test_util.h	Wed Aug 07 11:55:15 2019 +0200
    15.2 +++ b/test/include/test_util.h	Wed Aug 07 12:00:56 2019 +0200
    15.3 @@ -14,6 +14,44 @@
    15.4  
    15.5  bool file_exists(std::string filename);
    15.6  
    15.7 +typedef enum _pEp_test_ident_preset {
    15.8 +    ALICE,
    15.9 +    APPLE,
   15.10 +    BOB,
   15.11 +    CAROL,
   15.12 +    DAVE,
   15.13 +    ERIN,
   15.14 +    FRANK,
   15.15 +    GABRIELLE,
   15.16 +    JOHN,
   15.17 +    ALEX,
   15.18 +    ALEX_0,
   15.19 +    ALEX_1,
   15.20 +    ALEX_2,
   15.21 +    ALEX_3,
   15.22 +    ALEX_4,
   15.23 +    ALEX_5,
   15.24 +    ALEX_6A,
   15.25 +    ALEX_6B,
   15.26 +    ALEX_6C,
   15.27 +    ALEX_6D,
   15.28 +    BELLA,
   15.29 +    FENRIS,
   15.30 +    SERCULLEN,
   15.31 +    INQUISITOR,
   15.32 +    BERND
   15.33 +} pEp_test_ident_preset;
   15.34 +
   15.35 +PEP_STATUS set_up_preset(PEP_SESSION session,
   15.36 +                         pEp_test_ident_preset preset_name,
   15.37 +                         bool set_identity, 
   15.38 +                         bool set_pep,
   15.39 +                         bool trust,
   15.40 +                         bool set_own, 
   15.41 +                         bool setup_private, 
   15.42 +                         pEp_identity** ident);
   15.43 +
   15.44 +
   15.45  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname);
   15.46  PEP_STATUS set_up_ident_from_scratch(PEP_SESSION session, 
   15.47                                       const char* key_fname,
    16.1 --- a/test/src/SuiteMaker.cc	Wed Aug 07 11:55:15 2019 +0200
    16.2 +++ b/test/src/SuiteMaker.cc	Wed Aug 07 12:00:56 2019 +0200
    16.3 @@ -21,14 +21,17 @@
    16.4  #include "Engine463Tests.h"
    16.5  #include "IOS1664Tests.h"
    16.6  #include "BloblistTests.h"
    16.7 +#include "KeyImportAndRetrieveTests.h"
    16.8  #include "NewUpdateIdAndMyselfTests.h"
    16.9  #include "NoOwnIdentWritesOnDecryptTests.h"
   16.10  #include "LiteralFilenameTests.h"
   16.11  #include "I18nTests.h"
   16.12 +#include "Message2_1Tests.h"
   16.13  #include "IdentityListTests.h"
   16.14  #include "PgpBinaryTests.h"
   16.15  #include "SubkeyRatingEvalTests.h"
   16.16  #include "MessageNullFromTests.h"
   16.17 +#include "Engine587Tests.h"
   16.18  #include "ExportKeyTests.h"
   16.19  #include "LeastCommonDenomColorTests.h"
   16.20  #include "StringlistTests.h"
   16.21 @@ -46,6 +49,7 @@
   16.22  #include "BlacklistAcceptNewKeyTests.h"
   16.23  #include "DecryptAttachPrivateKeyUntrustedTests.h"
   16.24  #include "BlacklistTests.h"
   16.25 +#include "GetKeyRatingForUserTests.h"
   16.26  #include "RevokeRegenAttachTests.h"
   16.27  #include "PepSubjectReceivedTests.h"
   16.28  #include "SequenceTests.h"
   16.29 @@ -88,14 +92,17 @@
   16.30      "Engine463Tests",
   16.31      "IOS1664Tests",
   16.32      "BloblistTests",
   16.33 +    "KeyImportAndRetrieveTests",
   16.34      "NewUpdateIdAndMyselfTests",
   16.35      "NoOwnIdentWritesOnDecryptTests",
   16.36      "LiteralFilenameTests",
   16.37      "I18nTests",
   16.38 +    "Message2_1Tests",
   16.39      "IdentityListTests",
   16.40      "PgpBinaryTests",
   16.41      "SubkeyRatingEvalTests",
   16.42      "MessageNullFromTests",
   16.43 +    "Engine587Tests",
   16.44      "ExportKeyTests",
   16.45      "LeastCommonDenomColorTests",
   16.46      "StringlistTests",
   16.47 @@ -113,6 +120,7 @@
   16.48      "BlacklistAcceptNewKeyTests",
   16.49      "DecryptAttachPrivateKeyUntrustedTests",
   16.50      "BlacklistTests",
   16.51 +    "GetKeyRatingForUserTests",
   16.52      "RevokeRegenAttachTests",
   16.53      "PepSubjectReceivedTests",
   16.54      "SequenceTests",
   16.55 @@ -146,7 +154,7 @@
   16.56  };
   16.57  
   16.58  // This file is generated, so magic constants are ok.
   16.59 -int SuiteMaker::num_suites = 63;
   16.60 +int SuiteMaker::num_suites = 68;
   16.61  
   16.62  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   16.63      if (strcmp(test_class_name, "URIAddressTests") == 0)
   16.64 @@ -167,6 +175,8 @@
   16.65          *test_suite = new IOS1664Tests(test_class_name, test_home);
   16.66      else if (strcmp(test_class_name, "BloblistTests") == 0)
   16.67          *test_suite = new BloblistTests(test_class_name, test_home);
   16.68 +    else if (strcmp(test_class_name, "KeyImportAndRetrieveTests") == 0)
   16.69 +        *test_suite = new KeyImportAndRetrieveTests(test_class_name, test_home);
   16.70      else if (strcmp(test_class_name, "NewUpdateIdAndMyselfTests") == 0)
   16.71          *test_suite = new NewUpdateIdAndMyselfTests(test_class_name, test_home);
   16.72      else if (strcmp(test_class_name, "NoOwnIdentWritesOnDecryptTests") == 0)
   16.73 @@ -175,6 +185,8 @@
   16.74          *test_suite = new LiteralFilenameTests(test_class_name, test_home);
   16.75      else if (strcmp(test_class_name, "I18nTests") == 0)
   16.76          *test_suite = new I18nTests(test_class_name, test_home);
   16.77 +    else if (strcmp(test_class_name, "Message2_1Tests") == 0)
   16.78 +        *test_suite = new Message2_1Tests(test_class_name, test_home);
   16.79      else if (strcmp(test_class_name, "IdentityListTests") == 0)
   16.80          *test_suite = new IdentityListTests(test_class_name, test_home);
   16.81      else if (strcmp(test_class_name, "PgpBinaryTests") == 0)
   16.82 @@ -183,6 +195,8 @@
   16.83          *test_suite = new SubkeyRatingEvalTests(test_class_name, test_home);
   16.84      else if (strcmp(test_class_name, "MessageNullFromTests") == 0)
   16.85          *test_suite = new MessageNullFromTests(test_class_name, test_home);
   16.86 +    else if (strcmp(test_class_name, "Engine587Tests") == 0)
   16.87 +        *test_suite = new Engine587Tests(test_class_name, test_home);
   16.88      else if (strcmp(test_class_name, "ExportKeyTests") == 0)
   16.89          *test_suite = new ExportKeyTests(test_class_name, test_home);
   16.90      else if (strcmp(test_class_name, "LeastCommonDenomColorTests") == 0)
   16.91 @@ -217,6 +231,8 @@
   16.92          *test_suite = new DecryptAttachPrivateKeyUntrustedTests(test_class_name, test_home);
   16.93      else if (strcmp(test_class_name, "BlacklistTests") == 0)
   16.94          *test_suite = new BlacklistTests(test_class_name, test_home);
   16.95 +    else if (strcmp(test_class_name, "GetKeyRatingForUserTests") == 0)
   16.96 +        *test_suite = new GetKeyRatingForUserTests(test_class_name, test_home);
   16.97      else if (strcmp(test_class_name, "RevokeRegenAttachTests") == 0)
   16.98          *test_suite = new RevokeRegenAttachTests(test_class_name, test_home);
   16.99      else if (strcmp(test_class_name, "PepSubjectReceivedTests") == 0)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/src/engine_tests/GetKeyRatingForUserTests.cc	Wed Aug 07 12:00:56 2019 +0200
    17.3 @@ -0,0 +1,46 @@
    17.4 +// This file is under GNU General Public License 3.0
    17.5 +// see LICENSE.txt
    17.6 +
    17.7 +#include <stdlib.h>
    17.8 +#include <cstring>
    17.9 +#include <string>
   17.10 +
   17.11 +#include <cpptest.h>
   17.12 +#include "test_util.h"
   17.13 +
   17.14 +#include "pEpEngine.h"
   17.15 +
   17.16 +#include "EngineTestIndividualSuite.h"
   17.17 +#include "GetKeyRatingForUserTests.h"
   17.18 +
   17.19 +using namespace std;
   17.20 +
   17.21 +GetKeyRatingForUserTests::GetKeyRatingForUserTests(string suitename, string test_home_dir) :
   17.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   17.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("GetKeyRatingForUserTests::check_get_key_rating_for_user"),
   17.24 +                                                                      static_cast<Func>(&GetKeyRatingForUserTests::check_get_key_rating_for_user)));
   17.25 +}
   17.26 +
   17.27 +void GetKeyRatingForUserTests::check_get_key_rating_for_user() {
   17.28 +    pEp_identity* alice = NULL;
   17.29 +    PEP_STATUS status = set_up_preset(session, ALICE, false, false, false, false, false, &alice);
   17.30 +    pEp_identity* test_null = NULL;
   17.31 +    const char* fpr_save = alice->fpr;
   17.32 +    alice->fpr = NULL;
   17.33 +    status = get_identity(session, alice->address, alice->user_id, &test_null);
   17.34 +    TEST_ASSERT(!test_null);
   17.35 +    TEST_ASSERT(status == PEP_CANNOT_FIND_IDENTITY);
   17.36 +    TEST_ASSERT_MSG(alice->comm_type == PEP_ct_unknown, tl_ct_string(alice->comm_type));
   17.37 +
   17.38 +    // Ok, so we have no info really, let's set it.
   17.39 +    status = set_identity(session, alice);
   17.40 +    
   17.41 +    status = update_identity(session, alice);
   17.42 +    TEST_ASSERT(alice->fpr);
   17.43 +
   17.44 +    PEP_rating rating;
   17.45 +    status = get_key_rating_for_user(session, alice->user_id, alice->fpr, &rating);
   17.46 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   17.47 +    cout << tl_rating_string(rating) << endl;
   17.48 +    TEST_ASSERT(true);
   17.49 +}
    18.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 11:55:15 2019 +0200
    18.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 12:00:56 2019 +0200
    18.3 @@ -27,8 +27,9 @@
    18.4      TEST_ASSERT(!email.empty());
    18.5      
    18.6      message* message_mail = NULL;
    18.7 +    bool raise_att;
    18.8      
    18.9 -    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail);
   18.10 +    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail, &raise_att);
   18.11      TEST_ASSERT(status == PEP_STATUS_OK && message_mail);
   18.12      
   18.13      // create own identity here, because we want to reply, before we start.
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/src/engine_tests/Message2_1Tests.cc	Wed Aug 07 12:00:56 2019 +0200
    19.3 @@ -0,0 +1,579 @@
    19.4 +// This file is under GNU General Public License 3.0
    19.5 +// see LICENSE.txt
    19.6 +
    19.7 +#include <stdlib.h>
    19.8 +#include <cstring>
    19.9 +#include <string>
   19.10 +
   19.11 +#include <cpptest.h>
   19.12 +#include "test_util.h"
   19.13 +
   19.14 +#include "pEpEngine.h"
   19.15 +
   19.16 +#include "EngineTestIndividualSuite.h"
   19.17 +#include "Message2_1Tests.h"
   19.18 +
   19.19 +using namespace std;
   19.20 +
   19.21 +Message2_1Tests::Message2_1Tests(string suitename, string test_home_dir) :
   19.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   19.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0"),
   19.24 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0)));
   19.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_OpenPGP"),
   19.26 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_OpenPGP)));
   19.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1"),
   19.28 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1)));
   19.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP"),
   19.30 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP)));
   19.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0_from_msg"),
   19.32 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0_from_msg)));
   19.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1_from_msg"),
   19.34 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1_from_msg)));
   19.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_2_0"),
   19.36 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_2_0)));
   19.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP"),
   19.38 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP)));
   19.39 +}
   19.40 +
   19.41 +bool Message2_1Tests::verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout) {
   19.42 +    if (!maj_inout || !min_inout)
   19.43 +        return false;
   19.44 +    int major = *maj_inout;
   19.45 +    int minor = *min_inout;
   19.46 +    
   19.47 +    char* ptext = NULL;
   19.48 +    size_t psize = 0;
   19.49 +    stringlist_t* keylist = NULL;
   19.50 +    
   19.51 +    PEP_STATUS status = decrypt_and_verify(session, enc_msg->attachments->next->value,
   19.52 +                                           enc_msg->attachments->next->size, NULL, 0,
   19.53 +                                           &ptext, &psize, &keylist,
   19.54 +                                           NULL);
   19.55 +
   19.56 +    cout << ptext << endl;
   19.57 +
   19.58 +    // fixme, check status
   19.59 +    if (strstr(ptext, "pEp-Wrapped-Message-Info: OUTER") != NULL && strstr(ptext, "pEp-Wrapped-Message-Info: INNER") != NULL) {
   19.60 +        *maj_inout = 2;
   19.61 +        *min_inout = 0;
   19.62 +    }
   19.63 +    else if (strstr(ptext, "X-pEp-Wrapped-Message-Info: INNER") != NULL && strstr(ptext, "forwarded=\"no\"") != NULL) {
   19.64 +        *maj_inout = 2;
   19.65 +        *min_inout = 1;
   19.66 +    }
   19.67 +    else {
   19.68 +        *maj_inout = 1;
   19.69 +        *min_inout = 0;
   19.70 +    }    
   19.71 +    
   19.72 +    switch (major) {
   19.73 +        case 1:
   19.74 +            if (*maj_inout == 1)
   19.75 +                return true;
   19.76 +            return false;    
   19.77 +        case 2:
   19.78 +            if (*maj_inout != 2)
   19.79 +                return false;
   19.80 +            if (*min_inout == minor)
   19.81 +                return true;
   19.82 +            return false;    
   19.83 +        default:
   19.84 +            *maj_inout = 0;
   19.85 +            *min_inout = 0;
   19.86 +            return false;
   19.87 +    }
   19.88 +}
   19.89 +
   19.90 +void Message2_1Tests::check_message2_1_recip_2_0() {
   19.91 +
   19.92 +    pEp_identity* alice = NULL;
   19.93 +    pEp_identity* carol = NULL;
   19.94 +    
   19.95 +    PEP_STATUS status = set_up_preset(session, ALICE, 
   19.96 +                                      true, true, true, true, true, &alice);
   19.97 +
   19.98 +    TEST_ASSERT(status == PEP_STATUS_OK);
   19.99 +    TEST_ASSERT(alice);
  19.100 +    
  19.101 +    status = set_up_preset(session, CAROL, 
  19.102 +                           false, true, false, false, false, &carol);
  19.103 +
  19.104 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.105 +    TEST_ASSERT(carol);
  19.106 +
  19.107 +    // default should be 2.0 after setting pep status
  19.108 +    status = update_identity(session, carol);
  19.109 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.110 +    TEST_ASSERT(carol->major_ver == 2);
  19.111 +    TEST_ASSERT(carol->minor_ver == 0);
  19.112 +    // generate message
  19.113 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  19.114 +    
  19.115 +    message* msg = new_message(PEP_dir_outgoing);
  19.116 +    
  19.117 +    msg->from = alice;
  19.118 +    msg->to = new_identity_list(carol_to);
  19.119 +    msg->shortmsg = strdup("Boom shaka laka");
  19.120 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.121 +    
  19.122 +    message* enc_msg = NULL;
  19.123 +
  19.124 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.125 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.126 +    
  19.127 +    // ensure sent message is in 2.0 format
  19.128 +    unsigned int major = 2;
  19.129 +    unsigned int minor = 0;
  19.130 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.131 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.132 +    
  19.133 +    free_identity(carol);
  19.134 +    free_message(msg);
  19.135 +    free_message(enc_msg);
  19.136 +}
  19.137 +
  19.138 +/* PEP_STATUS set_up_preset(PEP_SESSION session,
  19.139 +                         pEp_test_ident_preset preset_name,
  19.140 +                         bool set_ident, 
  19.141 +                         bool set_pep,
  19.142 +                         bool trust,
  19.143 +                         bool set_own, 
  19.144 +                         bool setup_private, 
  19.145 +                         pEp_identity** ident) {
  19.146 +*/
  19.147 +
  19.148 +void Message2_1Tests::check_message2_1_recip_OpenPGP() {
  19.149 +    // set recip to 1.0
  19.150 +    pEp_identity* alice = NULL;
  19.151 +    pEp_identity* carol = NULL;
  19.152 +    
  19.153 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  19.154 +                                      true, true, true, true, true, &alice);
  19.155 +
  19.156 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.157 +    TEST_ASSERT(alice);
  19.158 +    
  19.159 +    status = set_up_preset(session, CAROL, 
  19.160 +                           false, false, false, false, false, &carol);
  19.161 +
  19.162 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.163 +    TEST_ASSERT(carol);
  19.164 +
  19.165 +    status = update_identity(session, carol);
  19.166 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.167 +    TEST_ASSERT(carol->major_ver < 2);
  19.168 +    TEST_ASSERT(carol->minor_ver == 0);
  19.169 +
  19.170 +    // generate message
  19.171 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  19.172 +    
  19.173 +    message* msg = new_message(PEP_dir_outgoing);
  19.174 +    
  19.175 +    msg->from = alice;
  19.176 +    msg->to = new_identity_list(carol_to);
  19.177 +    msg->shortmsg = strdup("Boom shaka laka");
  19.178 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.179 +    
  19.180 +    message* enc_msg = NULL;
  19.181 +
  19.182 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.183 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.184 +    
  19.185 +    // ensure sent message is in 1.0 format
  19.186 +    unsigned int major = 1;
  19.187 +    unsigned int minor = 0;
  19.188 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.189 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.190 +    
  19.191 +    free_identity(carol);
  19.192 +    free_message(msg);
  19.193 +    free_message(enc_msg);
  19.194 +}
  19.195 +
  19.196 +void Message2_1Tests::check_message2_1_recip_2_1() {
  19.197 +    // set recip to 2.1
  19.198 +    
  19.199 +    pEp_identity* alice = NULL;
  19.200 +    pEp_identity* carol = NULL;
  19.201 +    
  19.202 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  19.203 +                                      true, true, true, true, true, &alice);
  19.204 +
  19.205 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.206 +    TEST_ASSERT(alice);
  19.207 +    
  19.208 +    status = set_up_preset(session, CAROL, 
  19.209 +                           true, true, false, false, false, &carol);
  19.210 +
  19.211 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.212 +    TEST_ASSERT(carol);
  19.213 +
  19.214 +    status = set_pEp_version(session, carol, 2, 1);
  19.215 +    
  19.216 +    // default should be 2.1 after setting pep status
  19.217 +    status = update_identity(session, carol);
  19.218 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.219 +    TEST_ASSERT(carol->major_ver == 2);
  19.220 +    TEST_ASSERT(carol->minor_ver == 1);
  19.221 +    // generate message
  19.222 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  19.223 +    
  19.224 +    message* msg = new_message(PEP_dir_outgoing);
  19.225 +    
  19.226 +    msg->from = alice;
  19.227 +    msg->to = new_identity_list(carol_to);
  19.228 +    msg->shortmsg = strdup("Boom shaka laka");
  19.229 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.230 +    
  19.231 +    message* enc_msg = NULL;
  19.232 +
  19.233 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.234 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.235 +    
  19.236 +    // ensure sent message is in 2.0 format
  19.237 +    unsigned int major = 2;
  19.238 +    unsigned int minor = 1;
  19.239 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.240 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.241 +    
  19.242 +    free_identity(carol);
  19.243 +    free_message(msg);
  19.244 +    free_message(enc_msg);
  19.245 +    TEST_ASSERT(true);
  19.246 +}
  19.247 +
  19.248 +void Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP() {
  19.249 +    pEp_identity* alex = NULL;
  19.250 +    
  19.251 +    PEP_STATUS status = set_up_preset(session, ALEX_0, 
  19.252 +                                      true, true, true, true, true, &alex);
  19.253 +
  19.254 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.255 +    TEST_ASSERT(alex);
  19.256 +
  19.257 +    // receive 1.0 message from OpenPGP
  19.258 +    string incoming = slurp("test_mails/From_M1_0.eml");
  19.259 +    
  19.260 +    char* dec_msg;
  19.261 +    char* mod_src = NULL;
  19.262 +    PEP_decrypt_flags_t flags = 0;
  19.263 +    stringlist_t* keylist_used = NULL;
  19.264 +    PEP_rating rating;
  19.265 +    
  19.266 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  19.267 +
  19.268 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  19.269 +    // generate message
  19.270 +    
  19.271 +    message* msg = new_message(PEP_dir_outgoing);
  19.272 +    
  19.273 +    msg->from = alex;
  19.274 +    msg->to = new_identity_list(new_identity("pep-test-carol@pep-project.org", NULL, NULL, NULL));
  19.275 +    msg->shortmsg = strdup("Boom shaka laka");
  19.276 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.277 +    
  19.278 +    message* enc_msg = NULL;
  19.279 +
  19.280 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.281 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.282 +    
  19.283 +    // ensure sent message is in 1.0 format
  19.284 +    unsigned int major = 1;
  19.285 +    unsigned int minor = 0;
  19.286 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.287 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.288 +    
  19.289 +    free_message(msg);
  19.290 +    free_message(enc_msg);
  19.291 +    free(dec_msg);
  19.292 +    free(mod_src);
  19.293 +    TEST_ASSERT(true);
  19.294 +}
  19.295 +
  19.296 +void Message2_1Tests::check_message2_1_recip_2_0_from_msg() {
  19.297 +    // receive 2.0 message
  19.298 +    pEp_identity* carol = NULL;
  19.299 +    
  19.300 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  19.301 +                                      true, true, true, true, true, &carol);
  19.302 +
  19.303 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.304 +    TEST_ASSERT(carol);
  19.305 +
  19.306 +    // receive 1.0 message from OpenPGP
  19.307 +    string incoming = slurp("test_mails/2_0_msg.eml");
  19.308 +    
  19.309 +    char* dec_msg;
  19.310 +    char* mod_src = NULL;
  19.311 +    PEP_decrypt_flags_t flags = 0;
  19.312 +    stringlist_t* keylist_used = NULL;
  19.313 +    PEP_rating rating;
  19.314 +    
  19.315 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  19.316 +
  19.317 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  19.318 +    // generate message
  19.319 +    
  19.320 +    message* msg = new_message(PEP_dir_outgoing);
  19.321 +    
  19.322 +    msg->from = carol;
  19.323 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  19.324 +    msg->shortmsg = strdup("Boom shaka laka");
  19.325 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.326 +    
  19.327 +    message* enc_msg = NULL;
  19.328 +
  19.329 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.330 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.331 +    
  19.332 +    // ensure sent message is in 1.0 format
  19.333 +    unsigned int major = 2;
  19.334 +    unsigned int minor = 0;
  19.335 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.336 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.337 +    
  19.338 +    free_message(msg);
  19.339 +    free_message(enc_msg);
  19.340 +    free(dec_msg);
  19.341 +    free(mod_src);
  19.342 +}
  19.343 +
  19.344 +void Message2_1Tests::check_message2_1_recip_2_1_from_msg() {
  19.345 +    // receive 2.1 message
  19.346 +    pEp_identity* carol = NULL;
  19.347 +    
  19.348 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  19.349 +                                      true, true, true, true, true, &carol);
  19.350 +
  19.351 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.352 +    TEST_ASSERT(carol);
  19.353 +
  19.354 +    // receive 1.0 message from OpenPGP
  19.355 +    string incoming = slurp("test_mails/From_M2_1.eml");
  19.356 +    
  19.357 +    char* dec_msg;
  19.358 +    char* mod_src = NULL;
  19.359 +    PEP_decrypt_flags_t flags = 0;
  19.360 +    stringlist_t* keylist_used = NULL;
  19.361 +    PEP_rating rating;
  19.362 +    
  19.363 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  19.364 +
  19.365 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  19.366 +    // generate message
  19.367 +    
  19.368 +    message* msg = new_message(PEP_dir_outgoing);
  19.369 +    
  19.370 +    msg->from = carol;
  19.371 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  19.372 +    msg->shortmsg = strdup("Boom shaka laka");
  19.373 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.374 +    
  19.375 +    message* enc_msg = NULL;
  19.376 +
  19.377 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.378 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.379 +    
  19.380 +    // ensure sent message is in 2.1 format
  19.381 +    unsigned int major = 2;
  19.382 +    unsigned int minor = 1;
  19.383 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.384 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.385 +    
  19.386 +    free_message(msg);
  19.387 +    free_message(enc_msg);
  19.388 +    free(dec_msg);
  19.389 +    free(mod_src);
  19.390 +}
  19.391 +
  19.392 +void Message2_1Tests::check_message2_1_recip_mixed_2_0() {
  19.393 +    // Set mixed recipient values
  19.394 +    pEp_identity* alice = NULL;
  19.395 +    pEp_identity* bob = NULL;
  19.396 +    pEp_identity* carol = NULL;
  19.397 +    pEp_identity* dave = NULL;
  19.398 +    pEp_identity* alex = NULL;
  19.399 +
  19.400 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  19.401 +                                      true, true, true, true, true, &alice);
  19.402 +
  19.403 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.404 +    TEST_ASSERT(alice);
  19.405 +
  19.406 +    status = set_up_preset(session, BOB, 
  19.407 +                           true, true, false, false, false, &bob);
  19.408 +
  19.409 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.410 +    TEST_ASSERT(bob);
  19.411 +
  19.412 +    status = set_pEp_version(session, bob, 2, 1);
  19.413 +
  19.414 +    // default should be 2.1 after setting pep status
  19.415 +    status = update_identity(session, bob);
  19.416 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.417 +    TEST_ASSERT(bob->major_ver == 2);
  19.418 +    TEST_ASSERT(bob->minor_ver == 1);
  19.419 +    
  19.420 +    status = set_up_preset(session, CAROL, 
  19.421 +                           true, true, false, false, false, &carol);
  19.422 +
  19.423 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.424 +    TEST_ASSERT(carol);
  19.425 +
  19.426 +    status = set_pEp_version(session, carol, 2, 1);
  19.427 +
  19.428 +    // default should be 2.1 after setting pep status
  19.429 +    status = update_identity(session, carol);
  19.430 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.431 +    TEST_ASSERT(carol->major_ver == 2);
  19.432 +    TEST_ASSERT(carol->minor_ver == 1);
  19.433 +    
  19.434 +    status = set_up_preset(session, DAVE, 
  19.435 +                           true, true, false, false, false, &dave);
  19.436 +
  19.437 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.438 +    TEST_ASSERT(dave);
  19.439 +
  19.440 +    status = set_pEp_version(session, dave, 2, 0);
  19.441 +
  19.442 +    // default should be 2.1 after setting pep status
  19.443 +    status = update_identity(session, dave);
  19.444 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.445 +    TEST_ASSERT(dave->major_ver == 2);
  19.446 +    TEST_ASSERT(dave->minor_ver == 0);
  19.447 +
  19.448 +    status = set_up_preset(session, ALEX, 
  19.449 +                           true, true, true, false, false, &alex);
  19.450 +
  19.451 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.452 +    TEST_ASSERT(alex);
  19.453 +
  19.454 +    status = set_pEp_version(session, alex, 2, 1);
  19.455 +
  19.456 +    // default should be 2.1 after setting pep status
  19.457 +    status = update_identity(session, alex);
  19.458 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.459 +    TEST_ASSERT(alex->major_ver == 2);
  19.460 +    TEST_ASSERT(alex->minor_ver == 1);
  19.461 +
  19.462 +    // generate message
  19.463 +    message* msg = new_message(PEP_dir_outgoing);
  19.464 +    
  19.465 +    msg->from = alice;
  19.466 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  19.467 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  19.468 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  19.469 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  19.470 +    msg->shortmsg = strdup("Boom shaka laka");
  19.471 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.472 +    
  19.473 +    message* enc_msg = NULL;
  19.474 +
  19.475 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.476 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.477 +    
  19.478 +    // ensure sent message is in 2.0 format
  19.479 +    unsigned int major = 2;
  19.480 +    unsigned int minor = 0;
  19.481 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.482 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.483 +    
  19.484 +    free_message(msg);
  19.485 +    free_message(enc_msg);
  19.486 +}
  19.487 +
  19.488 +void Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP() {
  19.489 +    // Set mixed recipient values
  19.490 +    pEp_identity* alice = NULL;
  19.491 +    pEp_identity* bob = NULL;
  19.492 +    pEp_identity* carol = NULL;
  19.493 +    pEp_identity* dave = NULL;
  19.494 +    pEp_identity* alex = NULL;
  19.495 +
  19.496 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  19.497 +                                      true, true, true, true, true, &alice);
  19.498 +
  19.499 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.500 +    TEST_ASSERT(alice);
  19.501 +
  19.502 +    status = set_up_preset(session, BOB, 
  19.503 +                           true, true, false, false, false, &bob);
  19.504 +
  19.505 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.506 +    TEST_ASSERT(bob);
  19.507 +
  19.508 +    status = set_pEp_version(session, bob, 2, 1);
  19.509 +
  19.510 +    // default should be 2.1 after setting pep status
  19.511 +    status = update_identity(session, bob);
  19.512 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.513 +    TEST_ASSERT(bob->major_ver == 2);
  19.514 +    TEST_ASSERT(bob->minor_ver == 1);
  19.515 +    
  19.516 +    status = set_up_preset(session, CAROL, 
  19.517 +                           true, true, false, false, false, &carol);
  19.518 +
  19.519 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.520 +    TEST_ASSERT(carol);
  19.521 +
  19.522 +    status = set_pEp_version(session, carol, 2, 1);
  19.523 +
  19.524 +    // default should be 2.1 after setting pep status
  19.525 +    status = update_identity(session, carol);
  19.526 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.527 +    TEST_ASSERT(carol->major_ver == 2);
  19.528 +    TEST_ASSERT(carol->minor_ver == 1);
  19.529 +    
  19.530 +    status = set_up_preset(session, DAVE, 
  19.531 +                           true, true, false, false, false, &dave);
  19.532 +
  19.533 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.534 +    TEST_ASSERT(dave);
  19.535 +
  19.536 +    status = set_pEp_version(session, dave, 2, 0);
  19.537 +
  19.538 +    // default should be 2.1 after setting pep status
  19.539 +    status = update_identity(session, dave);
  19.540 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.541 +    TEST_ASSERT(dave->major_ver == 2);
  19.542 +    TEST_ASSERT(dave->minor_ver == 0);
  19.543 +
  19.544 +    status = set_up_preset(session, ALEX, 
  19.545 +                           true, false, true, false, false, &alex);
  19.546 +
  19.547 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.548 +    TEST_ASSERT(alex);
  19.549 +
  19.550 +    status = set_pEp_version(session, alex, 1, 0);
  19.551 +
  19.552 +    // default should be 1.0 after setting pep status
  19.553 +    status = update_identity(session, alex);
  19.554 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.555 +    TEST_ASSERT(alex->major_ver == 1);
  19.556 +    TEST_ASSERT(alex->minor_ver == 0);
  19.557 +
  19.558 +    // generate message
  19.559 +    message* msg = new_message(PEP_dir_outgoing);
  19.560 +    
  19.561 +    msg->from = alice;
  19.562 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  19.563 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  19.564 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  19.565 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  19.566 +    msg->shortmsg = strdup("Boom shaka laka");
  19.567 +    msg->longmsg = strdup("Don't you get sick of these?");
  19.568 +    
  19.569 +    message* enc_msg = NULL;
  19.570 +
  19.571 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  19.572 +    TEST_ASSERT(status == PEP_STATUS_OK);
  19.573 +    
  19.574 +    // ensure sent message is in 2.0 format
  19.575 +    unsigned int major = 1;
  19.576 +    unsigned int minor = 0;
  19.577 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  19.578 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  19.579 +    
  19.580 +    free_message(msg);
  19.581 +    free_message(enc_msg);
  19.582 +}
    20.1 --- a/test/src/util/test_util.cc	Wed Aug 07 11:55:15 2019 +0200
    20.2 +++ b/test/src/util/test_util.cc	Wed Aug 07 12:00:56 2019 +0200
    20.3 @@ -6,6 +6,7 @@
    20.4  #include "TestConstants.h"
    20.5  #include "mime.h"
    20.6  #include "message_api.h"
    20.7 +#include "keymanagement.h"
    20.8  
    20.9  #include <fstream>
   20.10  #include <sstream>
   20.11 @@ -17,6 +18,8 @@
   20.12  #include <unistd.h>
   20.13  #include <ftw.h>
   20.14  
   20.15 +using namespace std;
   20.16 +
   20.17  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname) {
   20.18      const std::string key = slurp(fname);
   20.19      PEP_STATUS status = (key.empty() ? PEP_KEY_NOT_FOUND : PEP_STATUS_OK);
   20.20 @@ -184,6 +187,8 @@
   20.21              return "PEP_CANNOT_SET_PERSON";
   20.22          case PEP_CANNOT_SET_PGP_KEYPAIR:
   20.23              return "PEP_CANNOT_SET_PGP_KEYPAIR";
   20.24 +        case PEP_CANNOT_SET_PEP_VERSION:
   20.25 +            return "PEP_CANNOT_SET_PEP_VERSION";
   20.26          case PEP_CANNOT_SET_IDENTITY:
   20.27              return "PEP_CANNOT_SET_IDENTITY";
   20.28          case PEP_CANNOT_SET_TRUST:
   20.29 @@ -690,4 +695,253 @@
   20.30      return status;
   20.31  }
   20.32  
   20.33 +PEP_STATUS set_up_preset(PEP_SESSION session,
   20.34 +                         pEp_test_ident_preset preset_name,
   20.35 +                         bool set_ident, 
   20.36 +                         bool set_pep,
   20.37 +                         bool trust,
   20.38 +                         bool set_own, 
   20.39 +                         bool setup_private, 
   20.40 +                         pEp_identity** ident) {
   20.41 +    if (set_own && !set_ident)
   20.42 +        return PEP_ILLEGAL_VALUE;
   20.43 +        
   20.44 +    const char* name = NULL;
   20.45 +    const char* user_id = NULL;
   20.46 +    const char* email = NULL;
   20.47 +    const char* key_prefix = NULL;
   20.48 +    string pubkey_dir = "test_keys/pub/";
   20.49 +    string privkey_dir = "test_keys/priv/";
   20.50 +    const char* fpr = NULL;
   20.51 +    PEP_STATUS status = PEP_STATUS_OK;
   20.52 +    
   20.53 +    if (ident)
   20.54 +        *ident = NULL;
   20.55 +
   20.56 +    pEp_identity* retval = NULL;
   20.57 +        
   20.58 +    switch (preset_name) {
   20.59 +        case ALICE:
   20.60 +            name = "Alice Spivak Hyatt";
   20.61 +            user_id = "ALICE";
   20.62 +            email = "pep.test.alice@pep-project.org";
   20.63 +            key_prefix = "pep-test-alice-0x6FF00E97";
   20.64 +            fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   20.65 +            break;
   20.66 +        case APPLE:
   20.67 +            name = "Apple of my Computer";
   20.68 +            user_id = "APPLE";
   20.69 +            email = "pep.test.apple@pep-project.org";
   20.70 +            key_prefix = "pep-test-apple-0x1CCBC7D7";
   20.71 +            fpr = "3D8D9423D03DDF61B60161150313D94A1CCBC7D7";
   20.72 +            break;
   20.73 +        case BOB:
   20.74 +            name = "Bob Dog";
   20.75 +            user_id = "BOB";
   20.76 +            email = "pep.test.bob@pep-project.org";
   20.77 +            key_prefix = "pep-test-bob-0xC9C2EE39";
   20.78 +            fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
   20.79 +            break;
   20.80 +        case CAROL:
   20.81 +            name = "Carol Burnett";
   20.82 +            user_id = "CAROL";
   20.83 +            email = "pep-test-carol@pep-project.org";
   20.84 +            key_prefix = "pep-test-carol-0x42A85A42";
   20.85 +            fpr = "8DD4F5827B45839E9ACCA94687BDDFFB42A85A42";
   20.86 +            break;
   20.87 +        case DAVE:
   20.88 +            name = "The Hoff";
   20.89 +            user_id = "DAVE";
   20.90 +            email = "pep-test-dave@pep-project.org";
   20.91 +            key_prefix = "pep-test-dave-0xBB5BCCF6";
   20.92 +            fpr = "E8AC9779A2D13A15D8D55C84B049F489BB5BCCF6";
   20.93 +            break;
   20.94 +        case ERIN:
   20.95 +            name = "Erin Ireland";
   20.96 +            user_id = "ERIN";
   20.97 +            email = "pep-test-erin@pep-project.org";
   20.98 +            key_prefix = "pep-test-erin-0x9F8D7CBA";
   20.99 +            fpr = "1B0E197E8AE66277B8A024B9AEA69F509F8D7CBA";
  20.100 +            break;
  20.101 +        case FRANK:
  20.102 +            name = "Frank N. Furter";
  20.103 +            user_id = "FRANK";
  20.104 +            email = "pep-test-frank@pep-project.org";
  20.105 +            key_prefix = "pep-test-frank-0x9A7FC670";
  20.106 +            fpr = "B022B74476D8A8E1F01E55FBAB6972569A7FC670"; // currently expired
  20.107 +            break;
  20.108 +        case GABRIELLE:
  20.109 +            name = "Gabrielle Gonzales";
  20.110 +            user_id = "GABI";
  20.111 +            email = "pep-test-gabrielle@pep-project.org";
  20.112 +            key_prefix = "pep-test-gabrielle-0xE203586C";
  20.113 +            fpr = "906C9B8349954E82C5623C3C8C541BD4E203586C";
  20.114 +            break;
  20.115 +        case JOHN:
  20.116 +            name = "John Denver";
  20.117 +            user_id = "JOHN";
  20.118 +            email = "pep.test.john@pep-project.org";
  20.119 +            key_prefix = "pep-test-john-0x70DCF575";
  20.120 +            fpr = "AA2E4BEB93E5FE33DEFD8BE1135CD6D170DCF575";
  20.121 +            break;
  20.122 +        case ALEX:
  20.123 +            name = "Alex Braithwaite";
  20.124 +            user_id = "ALEX";
  20.125 +            email = "pep.test.alexander@peptest.ch";
  20.126 +            key_prefix = "pep.test.alexander-0x26B54E4E";
  20.127 +            fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
  20.128 +            break;
  20.129 +        case ALEX_0:
  20.130 +            name = "Alex Braithwaite";
  20.131 +            user_id = "ALEX";
  20.132 +            email = "pep.test.alexander0@darthmama.org";
  20.133 +            key_prefix = "pep.test.alexander0-0x3B7302DB";
  20.134 +            fpr = "F4598A17D4690EB3B5B0F6A344F04E963B7302DB";
  20.135 +            break;
  20.136 +        case ALEX_1:
  20.137 +            name = "Alex Braithwaite";
  20.138 +            user_id = "ALEX";
  20.139 +            email = "pep.test.alexander1@darthmama.org";
  20.140 +            key_prefix = "pep.test.alexander1-0x541260F6";
  20.141 +            fpr = "59AF4C51492283522F6904531C09730A541260F6";
  20.142 +            break;
  20.143 +        case ALEX_2:
  20.144 +            name = "Alex Braithwaite";
  20.145 +            user_id = "ALEX";
  20.146 +            email = "pep.test.alexander2@darthmama.org";
  20.147 +            key_prefix = "pep.test.alexander2-0xA6512F30";
  20.148 +            fpr = "46A994F19077C05610870273C4B8AB0BA6512F30";
  20.149 +            break;
  20.150 +        case ALEX_3:
  20.151 +            name = "Alex Braithwaite";
  20.152 +            user_id = "ALEX";
  20.153 +            email = "pep.test.alexander3@darthmama.org";
  20.154 +            key_prefix = "pep.test.alexander3-0x724B3975";
  20.155 +            fpr = "5F7076BBD92E14EA49F0DF7C2CE49419724B3975";
  20.156 +            break;
  20.157 +        case ALEX_4:
  20.158 +            name = "Alex Braithwaite";
  20.159 +            user_id = "ALEX";
  20.160 +            email = "pep.test.alexander4@darthmama.org";
  20.161 +            key_prefix = "pep.test.alexander4-0x844B9DCF";
  20.162 +            fpr = "E95FFF95B8E2FDD4A12C3374395F1485844B9DCF";
  20.163 +            break;
  20.164 +        case ALEX_5:
  20.165 +            name = "Alex Braithwaite";
  20.166 +            user_id = "ALEX";
  20.167 +            email = "pep.test.alexander5@darthmama.org";
  20.168 +            key_prefix = "pep.test.alexander5-0x0773CD29";
  20.169 +            fpr = "58BCC2BF2AE1E3C4FBEAB89AD7838ACA0773CD29";
  20.170 +            break;
  20.171 +        case ALEX_6A:
  20.172 +            name = "Alex Braithwaite";
  20.173 +            user_id = "ALEX";
  20.174 +            email = "pep.test.alexander6@darthmama.org";
  20.175 +            key_prefix = "pep.test.alexander6-0x0019697D";
  20.176 +            fpr = "74D79B4496E289BD8A71B70BA8E2C4530019697D";
  20.177 +            break;
  20.178 +        case ALEX_6B:
  20.179 +            name = "Alex Braithwaite";
  20.180 +            user_id = "ALEX";
  20.181 +            email = "pep.test.alexander6@darthmama.org";
  20.182 +            key_prefix = "pep.test.alexander6-0x503B14D8";
  20.183 +            fpr = "2E21325D202A44BFD9C607FCF095B202503B14D8";
  20.184 +            break;
  20.185 +        case ALEX_6C:
  20.186 +            name = "Alex Braithwaite";
  20.187 +            user_id = "ALEX";
  20.188 +            email = "pep.test.alexander6@darthmama.org";
  20.189 +            key_prefix = "pep.test.alexander6-0xA216E95A";
  20.190 +            fpr = "3C1E713D8519D7F907E3142D179EAA24A216E95A";
  20.191 +            break;
  20.192 +        case ALEX_6D:
  20.193 +            name = "Alex Braithwaite";
  20.194 +            user_id = "ALEX";
  20.195 +            email = "pep.test.alexander6@darthmama.org";
  20.196 +            key_prefix = "pep.test.alexander6-0xBDA17020";
  20.197 +            fpr = "B4CE2F6947B6947C500F0687AEFDE530BDA17020";
  20.198 +            break;
  20.199 +        case BELLA:
  20.200 +            name = "Bella Cat";
  20.201 +            user_id = "BELLA";
  20.202 +            email = "pep.test.bella@peptest.ch";
  20.203 +            key_prefix = "pep.test.bella-0xAF516AAE";
  20.204 +            fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  20.205 +            break;
  20.206 +        case FENRIS:
  20.207 +            name = "Fenris Leto Hawke";
  20.208 +            user_id = "FENRIS";
  20.209 +            email = "pep.test.fenris@thisstilldoesntwork.lu";
  20.210 +            key_prefix = "pep.test.fenris-0x4F3D2900";
  20.211 +            fpr = "0969FA229DF21C832A64A04711B1B9804F3D2900";
  20.212 +            break;
  20.213 +        case SERCULLEN:
  20.214 +            name = "Cullen Rutherford";
  20.215 +            user_id = "CULLEN";
  20.216 +            email = "sercullen-test@darthmama.org";
  20.217 +            key_prefix = "sercullen-0x3CEAADED4"; // NB expired on purpose
  20.218 +            fpr = "1C9666D8B3E28F4AA3847DA89A6E75E3CEAADED4";
  20.219 +            break;
  20.220 +        case INQUISITOR:
  20.221 +            name = "Inquisitor Claire Trevelyan";
  20.222 +            user_id = "INQUISITOR";
  20.223 +            email = "inquisitor@darthmama.org";
  20.224 +            key_prefix = "inquisitor-0xA4728718_renewed";
  20.225 +            fpr = "8E8D2381AE066ABE1FEE509821BA977CA4728718";
  20.226 +            break;
  20.227 +        case BERND:
  20.228 +            name = "Bernd das Brot";
  20.229 +            user_id = "BERNDI";
  20.230 +            email = "bernd.das.brot@darthmama.org";
  20.231 +            key_prefix = "bernd.das.brot-0xCAFAA422";
  20.232 +            fpr = "F8CE0F7E24EB190A2FCBFD38D4B088A7CAFAA422";
  20.233 +            break;
  20.234 +        default:
  20.235 +            return PEP_CANNOT_SET_IDENTITY;
  20.236 +    }
  20.237 +    
  20.238 +    string pubkey_file = pubkey_dir + key_prefix + "_pub.asc";
  20.239 +    string privkey_file = privkey_dir + key_prefix + "_priv.asc";
  20.240 +    
  20.241 +    if (!slurp_and_import_key(session, pubkey_file.c_str()))
  20.242 +        return PEP_KEY_NOT_FOUND;
  20.243 +
  20.244 +    if (setup_private) {    
  20.245 +        if (!slurp_and_import_key(session, privkey_file.c_str()))
  20.246 +            return PEP_KEY_NOT_FOUND;
  20.247 +    }
  20.248 +
  20.249 +    retval = new_identity(email, NULL, user_id, name);
  20.250 +    if (!retval)
  20.251 +        return PEP_OUT_OF_MEMORY;
  20.252 +        
  20.253 +    // honestly probably happens anyway  
  20.254 +    if (set_ident && status == PEP_STATUS_OK)
  20.255 +        status = set_identity(session, retval);
  20.256 +
  20.257 +    if (set_own) {
  20.258 +        retval->me = true;
  20.259 +        status = set_own_key(session, retval, fpr);
  20.260 +    }        
  20.261 +    
  20.262 +    if (set_pep && status == PEP_STATUS_OK)
  20.263 +        status = set_as_pEp_user(session, retval);
  20.264 +        
  20.265 +    if (trust && status == PEP_STATUS_OK) {
  20.266 +        if (!retval->me)
  20.267 +            status = update_identity(session, retval);
  20.268 +        if (retval->comm_type >= PEP_ct_strong_but_unconfirmed) {
  20.269 +            retval->comm_type = (PEP_comm_type)(retval->comm_type | PEP_ct_confirmed);
  20.270 +            status = set_trust(session, retval);
  20.271 +        }
  20.272 +    }
  20.273 +    
  20.274 +    
  20.275 +    if (ident)
  20.276 +        *ident = retval;
  20.277 +    else 
  20.278 +        free_identity(retval);
  20.279 +        
  20.280 +    return status;
  20.281 +}
  20.282  #endif
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/test_mails/From_M1_0.eml	Wed Aug 07 12:00:56 2019 +0200
    21.3 @@ -0,0 +1,159 @@
    21.4 +X-Envelope-From: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    21.5 +X-Envelope-To: <krista@darthmama.org>
    21.6 +X-Delivery-Time: 1565167147
    21.7 +X-UID: 1648
    21.8 +Return-Path: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    21.9 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   21.10 +Authentication-Results: strato.com; arc=none
   21.11 +Authentication-Results: strato.com; dkim=none
   21.12 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   21.13 +Authentication-Results: strato.com; spf=pass smtp.mailfrom="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de"
   21.14 +X-RZG-Expurgate: clean/normal
   21.15 +X-RZG-Expurgate-ID: 149500::1565167147-00003DDB-C7945173/0/0
   21.16 +X-RZG-CLASS-ID: mi00
   21.17 +Received-SPF: pass
   21.18 +	(strato.com: domain _spf.strato.com designates 2a01:238:20a:202:5100::3 as permitted sender)
   21.19 +	mechanism=ip6;
   21.20 +	client-ip=2a01:238:20a:202:5100::3;
   21.21 +	helo="mi6-p00-ob.smtp.rzone.de";
   21.22 +	envelope-from="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de";
   21.23 +	receiver=smtpin.rzone.de;
   21.24 +	identity=mailfrom;
   21.25 +Received: from mi6-p00-ob.smtp.rzone.de ([IPv6:2a01:238:20a:202:5100::3])
   21.26 +	by smtpin.rzone.de (RZmta 44.24 OK)
   21.27 +	with ESMTPS id A06378v778d77Mx
   21.28 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   21.29 +	(Client CN "*.smtp.rzone.de", Issuer "TeleSec ServerPass Class 2 CA" (verified OK (+EmiG)))
   21.30 +	(Client hostname verified OK)
   21.31 +	for <krista@darthmama.org>;
   21.32 +	Wed, 7 Aug 2019 10:39:07 +0200 (CEST)
   21.33 +X-RZG-FWD-BY: pep.test.alexander0@darthmama.org
   21.34 +Received: from mailin.rzone.de ([unix socket])
   21.35 +	by mailin.rzone.de (RZmta 44.24) with LMTPA;
   21.36 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   21.37 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   21.38 +Authentication-Results: strato.com; arc=none
   21.39 +Authentication-Results: strato.com; dkim=none
   21.40 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   21.41 +Authentication-Results: strato.com; spf=none smtp.mailfrom="pep-test-carol@pep-project.org"
   21.42 +X-RZG-Expurgate: clean/normal
   21.43 +X-RZG-Expurgate-ID: 149500::1565167131-00003DDB-FC731615/0/0
   21.44 +X-Strato-MessageType: email
   21.45 +X-RZG-CLASS-ID: mi00
   21.46 +Received-SPF: none
   21.47 +	client-ip=94.231.81.244;
   21.48 +	helo="dragon.pibit.ch";
   21.49 +	envelope-from="pep-test-carol@pep-project.org";
   21.50 +	receiver=smtpin.rzone.de;
   21.51 +	identity=mailfrom;
   21.52 +Received: from dragon.pibit.ch ([94.231.81.244])
   21.53 +	by smtpin.rzone.de (RZmta 44.24 OK)
   21.54 +	with ESMTPS id m04b52v778cp8lj
   21.55 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   21.56 +	(Client did not present a certificate)
   21.57 +	for <pep.test.alexander0@darthmama.org>;
   21.58 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   21.59 +Received: from localhost (localhost [127.0.0.1])
   21.60 +	by dragon.pibit.ch (Postfix) with ESMTP id 08F6A171C07C
   21.61 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:51 +0200 (CEST)
   21.62 +Received: from dragon.pibit.ch ([127.0.0.1])
   21.63 +	by localhost (dragon.pibit.ch [127.0.0.1]) (amavisd-new, port 10024)
   21.64 +	with ESMTP id OvZUPxZCJx_I for <pep.test.alexander0@darthmama.org>;
   21.65 +	Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   21.66 +Received: from [192.168.43.214] (ip-109-40-131-98.web.vodafone.de [109.40.131.98])
   21.67 +	by dragon.pibit.ch (Postfix) with ESMTPSA id AD2B8171C069
   21.68 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   21.69 +To: pep.test.alexander0@darthmama.org
   21.70 +From: pep-test-carol@pep-project.org
   21.71 +Subject: 1.0 Test Msg
   21.72 +Openpgp: preference=signencrypt
   21.73 +Message-ID: <967793b1-8d03-537c-1fca-2c18e029f5a4@pep.foundation>
   21.74 +Date: Wed, 7 Aug 2019 10:38:49 +0200
   21.75 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0)
   21.76 + Gecko/20100101 Thunderbird/60.8.0
   21.77 +MIME-Version: 1.0
   21.78 +Content-Type: multipart/encrypted;
   21.79 + protocol="application/pgp-encrypted";
   21.80 + boundary="FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO"
   21.81 +
   21.82 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   21.83 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   21.84 +Content-Type: application/pgp-encrypted
   21.85 +Content-Description: PGP/MIME version identification
   21.86 +
   21.87 +Version: 1
   21.88 +
   21.89 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   21.90 +Content-Type: application/octet-stream; name="encrypted.asc"
   21.91 +Content-Description: OpenPGP encrypted message
   21.92 +Content-Disposition: inline; filename="encrypted.asc"
   21.93 +
   21.94 +-----BEGIN PGP MESSAGE-----
   21.95 +
   21.96 +hQGMAwjkZzJfiW8+AQwA4TFiILeKBTdW3UQi8PcQKOzJE6pxgQL+B1gpOzjCRUel
   21.97 +n3drMe02EwZkmQcGwCmoIP9vdYw/mlEgsWvTbuv85CXXUyw8lJ5gT/u52H0/zHrU
   21.98 +yaJQu2WyCOVYEZv2qlVGw9pWSSW14Xh39aTiLwOKr4gtOoa7O9lbbyZI4TKVqn7d
   21.99 +8hUbEO/dScFFnzPTcUBwKsWmO4NBkQd9kW0v9kw2RtZwy47gYA+V1SlWiZAqsIV1
  21.100 +j1xUK4ZkWFfQlbh3aYX8RX1F5lwV56nR5bk0Jcpeu/NLSTUBJwck8IcgIQ+LnYZA
  21.101 +a4Fag+m+neEw0rkgdkAaD0Vb2GrOqG61p8uA5xkpcaOy+3QQb7DeeK1QKh22DFaS
  21.102 +MHZZynlcqYsurS/6iO9i7+OB+QbslWtnfItXJpKtwc24mLZp9Xp20gfO3KXElTIx
  21.103 +rI1S/LRwG0054CUwChVeO4OVr3mwmR/zMvw4XqFj0K/Cjx6qwy1esyl/FQfQrbZC
  21.104 +c05QW+ojpC6rGMFa4aGchQEMA6jr/28pI+hCAQf/ZNhBOn8pOARAW2csYHWtc8Fy
  21.105 +N0Sknn2VFvDLCI43P+HqgqZfqeu53WlbADJ8zd8xzi9riB+3HSMRS4bpD2WKOzut
  21.106 +RQmjdEZxLceA82clvY02AH1mpjMb9Axl0/FZRlmoqZtJEVMYDEeKXJmONr6M6J5n
  21.107 +agAsPiSX9H7fHkRBRvna6K3GUTZpftLuptTdR54YvMr6HR6+1M6847f6IXrza0I+
  21.108 ++IckY5iEL0JCTnSNYehEDfXVoq7AubsiuVMrXK313uKtrOnxPbeDz7OXxusfa/u9
  21.109 +y2A4YR8L3lj1F5ZiHEojfFnKU+k+P2dt/ydQjRo0WihtMhFHNKcZaS9AUUkE1tLr
  21.110 +AQXNiMOM3IdciqVMFNX8uKlpVOxi8/0ak7vzaPsEpp/x+gnFHNsBykQ+rMDC1D6p
  21.111 +kkEz9ukEqZmq5PvwRX51AbZMwoFBxWoLTEZU0/g2d2eSCY7FJUaCsMVxkrBjRR2K
  21.112 +GnCQjHqBazOyfF/qlUtRycXa7sQsSWV4ywU1h76xW9qrc8py+zz2bOJhgRUdTP0s
  21.113 +s2CTyKihoEkR9ORBMwbCG3ScwVF/xOFgz8xZQovHbvJGEZNNjIgfxibaSCPg3Bng
  21.114 +UdA/hkozmN4nxbmPWRafXvf9Zbf7ZAnRhelz32DfcSGzVwEdEWzPnHrEWmMkk0wf
  21.115 +tzVwLShpDKU8uf0XwOf3kNzbFeCD2IjOYBq3ddhCpzxr1ZBNPxeX8FW+3LYXZkJK
  21.116 +W7jVLoeFFfZxaYtlhDJ8/ZwbhIUcpu5e+U9hUek83DffCIm/Wsea2wdOv48+gc+h
  21.117 +vbTQsnJzVA+bJzsXryMpY77rngVoyU8YjEcXt3JTDxYgym6i895rxOZ0ZS4+j81a
  21.118 +CKgCVWO2vFslqg/nBqeCIVO6vRgv3Gie7/u91b3N1s0J5eeCl+QkLP4re1S/s9TD
  21.119 +e7AUum+3qrPSMwMS8Yns9WTlyqF5OS80R0iPPW8HtGT+hNFHMHxGy1wMUdabeD/M
  21.120 +WRnxyivnpQICfAJeN0rNMaJkB0phbb/zmqIO7j6yb3MTDA9R/C03h72fRd46Elai
  21.121 +jfBYdLjYrsdx7r5/z5igKCsvFSqozW68HdtNgqktPaG7HWbzsx1aQDjKi5O5bVuu
  21.122 +kQL75tZ58knss5v35HPLRbn4A4K8HGcX/N8UaYPQQXoZ4RjIOaeSPaWRTRw1zuj8
  21.123 +C9N7uXiVCyv4PNOZ+12Y6Tq3Xj/zkKHH5YsMs/sc9Nfz0AGVHaYHCqau8t1w40ab
  21.124 +/3AESAn6LO6P+97fFgsIq/Ox40MOdtMcQ7PIdySCcO3zzx5pp1dtoyJKCa4poXbs
  21.125 +T/ZEEMuwAMRLXVwVbfKST+OSUCJGs8vBEP/25wavKEVcwiRFbFpevlr1vSai2lVp
  21.126 +2UxXH5IBCdA6nXrNYIPLs2z0KyRgPI/SRovlWSeLGmaBcQiG23AuQJgtoRfE2BPk
  21.127 +iL3rdge+g3vzyqLwRiGsTMakwN8oYHgC6C+PO38L+u77Yu2gIzc55X9Dk15uQn99
  21.128 +8Q5w+EXZFMLZciZj2n1e1fQguoaF/QrJS0LFmftC5FC8e1o5vDorg56an8s3KlOW
  21.129 +tZnWBPqCoIkqwQPIvMuDSJpF/xTaOqRBqHEXwo9j3imodo7i40FxtinYgsMAvrY8
  21.130 +RuzKSgrpAIg1ADG79f4rpo8MVHNYKgFGUkc3P9YwrBMUCWJB2YYOV6v12ODo0NTt
  21.131 +P9Aep0+StCb5LiKT6YbfbA+wKIfkRdDddHw5ZR0NKOZjwK7HG3sxGsyWnpRsEYEv
  21.132 +o1pA7NKQa3kgSjpTeyYIVIF3CPJ+w7AlTUN30J5k3z+IeRYiTagr64lPjTYChPgT
  21.133 +fqG4ZdbWE9Dh0wO+jMm9a73ppVNBaGsFY4dg3x611vH6VoK1f1/9LVqW5bMNpIZz
  21.134 +vKh70giOnVnh0UpuK1Bnc8BUm3OMfYyVq5qiVj/4bGCAaNQcVNdbnLW7sXp+mLci
  21.135 +QBKGmlOZHQegoSRSyLIg60Z8FR1KDrIEZ0E5CaRAUdUA5WlPxTriDAUQa3zmNaaW
  21.136 +fe/87+0RbNpoJWPsG63XHVVkxgWk8472qpH9/qzqVrvrbiSB+VplJfQZL2LSVc7D
  21.137 +nJsTmTLNu5/VGt9L8lJzcwbhpfs9wiSVuPSgoovYRv4l9vrNpBaZzxdeicM0gZsy
  21.138 +Gdj/TSPd92zT7IOD70K8hWf8EHY0Uw/JkzJiFUHWNtw77M5ksTzOcarLw26s28EQ
  21.139 +iAPHAMmu0pdoyHlHYQY3wrDlesRbKSeilUvsxICXRvTlzx+SvV99Zs2/RfEAVD7X
  21.140 +DJL8FaS9ZwQvhGzcgAKq3SVo4v4FyaAWinSWSlE3f4ri+Xl7o/qvKMZ/kgnZxo+5
  21.141 +DGJ9M6qs2SLL8ICP9FOqC3eK/BnCcAbomN1hvDKPWJnluSBW7i6LXEq8dzp2YWR7
  21.142 +wljAJKuM29IWmYVTl+WzGDBQqHHUNGpymzUip+mBXlJG3n/3kaN8Snhk1qwes8Hi
  21.143 ++KaILwL2I8kFDuEO0xhqtErpbeMHUephLmSckgh4SdL+UdEC8JWfmth/PwX2b7US
  21.144 +ZA6co8X2ysPbni1Z61Df9rejZDMPTG2gm1Jn4kGUhwTBQnNBUUigNDukZxmJnagC
  21.145 +XZaUphij9kOsLQe6qXUqNXTmRmDKowSjkSu4/VIBUgdYKkIHMkfoNyWTn7MO2NUm
  21.146 +YGMQJLPqSheKM2WBwjlCrMHe5vuDH4OO0zjQWfJ0oPGrK5htMlmwjWYKjLXhmMPy
  21.147 +RRKil/PfKMCpZamiLFDt1YP9M62qTHktEuwIzjad/KERI3DOPmWszZWV36+b6s2q
  21.148 +ieasWYWIZHJBcTCc2AetjHlVvJrPPnMlOI6vS0OMYJVTiL5nzR2Rk6GkH1PXizqw
  21.149 +co/+Q4zLeC0Zx7u1FOdhX7s8a+qsV/kLbqczSMBOEDiMpcuQUGfB39XeuloOGkby
  21.150 +I/muioTiZqVKH06U6iZiAXktqdmsWOBABydeknKiBftpVc88eFQ9s7GTmidayjTF
  21.151 +FAuYmA3OP4dNlVImzuuB81qui28uNYF8LIwfpAukNU6yQQpU7sZhW7OuUq/KHjTq
  21.152 +aAtQuaHDgL8RD5HeYHx6w/RY1Ug9NGPEpNKsws1QzOvAS73vYKH0eILUONWd/JbV
  21.153 +0OB8ZQ0njP8CLcxrA5QZIMrhnw+k05wuPevfeFP/kvcfRuQu1qMhpqMt60M8PSHx
  21.154 +g1a2lGYzZV3d4VKZVuD4CZWg6eduqEQTKRx/nj2Fkfzdw5UVK8KdMhm2dX1a9Nzr
  21.155 +NNOf7wM5ypgkNGWvh/oxUJYVgKJUewN+9GzGn7L86WFyzcwVVllpcRKXCzz/1kNU
  21.156 +B3/tDbNvKntbgbNvMQNgMgHvW7H2NuZdHPjDxvkZQPRaKpquAx/zOHNjl1MASkJc
  21.157 +w4pEHRH2mssVX37Zi7C4qRu0F43nt+BiCYSixcCVXsHF2BKsKkSAV9elmcJWfAHo
  21.158 +sUuYMxKH4stfkWDNRQ==
  21.159 +=4k3/
  21.160 +-----END PGP MESSAGE-----
  21.161 +
  21.162 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO--
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/test/test_mails/From_M2_1.eml	Wed Aug 07 12:00:56 2019 +0200
    22.3 @@ -0,0 +1,124 @@
    22.4 +Message-ID: <pEp.PVUYXR.0AZSSOYBYY6MW.CEB1AB30-47AC-4B4D-AC1B-C3CF8F02D49D@pep-project.org>
    22.5 +From: Alice Spivak Hyatt <pep.test.alice@pep-project.org>
    22.6 +To: Carol Burnett <pep-test-carol@pep-project.org>
    22.7 +Subject: =?utf-8?Q?p=E2=89=A1p?=
    22.8 +X-pEp-Version: 2.1
    22.9 +MIME-Version: 1.0
   22.10 +Content-Type: multipart/encrypted; boundary="2eb141f241b71efb79e2a9e37545e146"; 
   22.11 + protocol="application/pgp-encrypted"
   22.12 +
   22.13 +--2eb141f241b71efb79e2a9e37545e146
   22.14 +Content-Type: application/pgp-encrypted
   22.15 +
   22.16 +Version: 1
   22.17 +--2eb141f241b71efb79e2a9e37545e146
   22.18 +Content-Type: application/octet-stream
   22.19 +Content-Transfer-Encoding: 7bit
   22.20 +Content-Disposition: inline; filename="msg.asc"
   22.21 +
   22.22 +-----BEGIN PGP MESSAGE-----
   22.23 +
   22.24 +wcBMA1oCBdlzCD9NAQgAlTYeWEzZy4kP4gD5m6d/QpGWVBZ9UFu9YqOSmiX3i+g1
   22.25 +DJyKPtYc9n1X5IDFr2VutmB73PLFgIySh3gV4LV2Nw9DMCFLo4LuamACXSmTYgfX
   22.26 +LwEi6X/tUl9gfnGWfokFDn5og/8g9fIAu3Iju+IoCYTxse3CbRzen6K88A/Eze1O
   22.27 +XW7W6lmo01CiqgJ++fxkuh68qfHROHIoiCo5cACdj98HKvtMPMLFXa+VIqDxKrt1
   22.28 +8jKGZxlA244MFfjHW5ICO6G0k1wQaUgw0PKRSBSshX6okKytfH3ckEkFNJVQZtRT
   22.29 +72j5I6ssuNUs53ymSzsrV5IrQhK/EsnhmnKBJ+GsosHATAOo6/9vKSPoQgEH/1DK
   22.30 +FH2UPlmflD3+07vlFZyoCwCYlcgN9sWl77bT5CTSFV4PK19F9vkaYcOwEbGxcS1D
   22.31 +z7OnHTFNTe3kVuM9kzWZ+F87+phGV6FWoAfuGAOWF3luZSop0quIJLwu1n3EtX0D
   22.32 +Xl5OchfLitcWxzrCXZHcvM+P4VEsIWudnJFC4hHHWgbbOF65B4dVEs3dINyVoTF6
   22.33 +z+iQImCn3EDPhcB9SlMZOob8hGUvUSTZDJJETZPHAJeW76NGQZ95fF/x9nqr/3/N
   22.34 +alGQ7Lq7R9Inv9BYlnXmJXTEnhLwFlwlPVoMf7pQnj3D0CYKP9AldrDNP2mQHYWO
   22.35 +Yac/3uDXiN5/QrLCMg3Sz8YBY9rS1pWV8ZZt+ZzY5jEIpdOUSw89mfEUDeZTNDo0
   22.36 +VoDzJvKn42NlRVQk4/6TVfaezgJjw/eVs0xLjOCGdsgCJ/PojExY+dfuo071Asbq
   22.37 +dCpc9qgNzDNJoS2XftTFHb1cH1ttC8an1ySLQNBg/9vguFAUxr+kAomfO1lRxpv5
   22.38 +BT2F7UBQTqWHqO4CPffsWQ5e6vCIx2c2FO3aFR0+WY3uTmlIZyjjMz1mB9KjjuO8
   22.39 +BgERxWd75ahoB3w8Hveel0vTussKpkLxxcQChhstcozoFX8M2VqVwVYqn7uChP9q
   22.40 +TPbuRVUpLvAAwKyO10eM+GZaHNbar7//v9KlCG1SLVE5PR8v5/n7L5slJwVfkqwR
   22.41 +9lZGtrSy4dB0lSfeQRwCd3iduu3oMdo2GeWU5duBdqqbrEGXAtubctZqXwzew1Vb
   22.42 +kNYuyozstv5B9psFSBshEaRGTFRGHuKB952AUeh8ISPX9IbucxNSbXxBRCOx/9Wj
   22.43 +1E9bm8WYZTT9r9Qwj1v0z0XfFze9i1nYWh8OVMCcsokhClBn46vDbY427cwSaS/O
   22.44 +luuqSL2B3Jhg4uCHNWHMjYvZh9jS50R7Do6aljQVK+TPk77LidAaNtG9fm04nL7+
   22.45 ++6+tLlMLKJ914i8t0rR8kTWtSp9xfzE59My56HOFsNZ3VAxrOaY2Xzxn67m8rXt5
   22.46 +0wXGy6yEQ9imoiQakZnOHWilE1BOplzIvdTugi2q8ILfqToE3t8vlSi9K39vUUTV
   22.47 +uj/Fw9vbGjfoeHt06mxHHSN3ePDj1v78jm8W10m+c0Zwrz3KrKW4B2WMrpqz8D6N
   22.48 +/PY/qJIccfCpCBZcZMO+6Wa4SWeYUyNn/JhhMCES9cpyllnZyVGrTb8l0NHhNG/P
   22.49 +eOuRa+5z7c/CtCSQlMlX2gti23q6j4mdm3HdaBQrW8uKvqKuh72pLDXUaY3EoDN7
   22.50 +g3V9I127hxd6K8KTKG/S18nlfHoSc9gVho4YOys9WEYE9S/Gznf4aU1lnnrjaKLF
   22.51 +B9w/RmWryqdu7hEl92j0zhdvQt6RI3/2rE7RN4XW7TtcmlnyWh6nfiqBLnS9zvU7
   22.52 +4hzukfMKQ91M8UfqpocQdxnxLk8TCw/RKhQP7onu9jR3nnPhtH54Ag3ohPxz+xBq
   22.53 +9k5K8Uo3JQXYFxs9hBYUc6WOLACQxOEmzMTApAr4nHObLp4Q74gd8FJ2KOmaWS13
   22.54 +vLJTmHroCw0w69dNZSUWQaSrn/enmXZ8Y4IOoZ17B5el5Ms76heYinjHY+sofi0I
   22.55 +cg2QrHxM+t0u7f9qaU0hbHWVt33i6AmGChu+0M/HyjSiEWv/Q5jE2lG0b/6yVl+f
   22.56 +C/6QUMg6Fr/6eVKuCeEYjVgoTMKDmQdo/w1SUSjfpVAdB/o6WL1lcv26k8HRsNZa
   22.57 +gEAPQuC/xEY8Vrou62etOh6tDO2jZ7ytd96aTcHvRIecilORhSOS7ClrNrBD8JJG
   22.58 +WGak9E5zBjLXXl8hSo+WMw0DOKacA6ccie0VRNlkg7QrGZD3S+FqKX/6Pv/YI7Q0
   22.59 ++RgS5hoKnj3vNmyAijJi2Nzksl+wjFZa5UnVsReynCZfOkZC+l5SrLwx5dX+NbG2
   22.60 +vdzGiw6ldLK/GO4n9tEIkpT0NfOLUbh26huhl59GWsv1XMA5R48J0vyqZCKfd6bG
   22.61 +V6wjEiELo0D7JMyhVsEqYMsr8DwyXH6yJ1UsKWDc/gKk6dx55SxJc8cBcu+s6qqg
   22.62 +mlXUGMXWj3VNHE4YeSd8BNA7f/yZSUTP6sO2fJsy5wuf8QcYNVE04bv2Vo7rnuaJ
   22.63 +9HpPwqwEeSqI5mjsdxwXHd434H7F7CCVUSqbkZe9jzsLC+Lb0xQYwtjk62pUq1CX
   22.64 +hI9k8YU5RuTeRv2Pg6Gzm17uXNG1wCZAWX2lWC+CgLpv+A0+ihy9srDnBZZPh2A+
   22.65 +ii9PKO36HlAszm6K/El/OGKN9El2PkberPblfFhfzXmPYLB5jiyMyIA/Vn9E4mp0
   22.66 +FyU7oFEttC0np9WGcExLPJWbL5dxqlAOKBuL0Rn+0+lvQjjb0aHQTku/yXE+6qlA
   22.67 +VwjbTT+4C4t6Jg4enJpAUZkzDVsr9hfkqkN1ezkjiNAJKD2NXD3nnOjHV0NMwfjL
   22.68 +Lm4vtOLJAKl3uMRFhqH0VkSbt4WuVe3hyro8LR7zstIfY7csEtcpk2RGCIFBqJjv
   22.69 +q1VSYpfg2ig5u06A2bDGY82GYmNAwnk3tEf1sBIdvLHDSHwKAQcmnlUAiMWoQRDA
   22.70 ++z+axP1qIUb1A7Ph7fqRQBLDQwqL0cT6f0dSy6oPT3IRd/R5C23AJB6G1HsSiBTP
   22.71 +i+lVdk14iseZW2yQcfXKq1mQCDMxP9ic6r+AaI7U70bGyVT/LM2LQ0JK0n5a9e31
   22.72 +llhu3XWoVrePhrPYo/nChSxkCjE/cmopeD/znKOSGPFYuxa1EEEjCN2R5Vm37kT4
   22.73 +say+GspHnatm8SGRSSRsiANl9hWnM/TdbeGZGUYZPV8kBqEMmX7mMic7T6ny8RZE
   22.74 +IWjMPZN9y4OygFNTD2KHd/krPfpvQSl7hRtjZJaDakNKxkMsKoTZjhGFDOqMeqoP
   22.75 +dufoxsCIV/oUPTRrgpQy4BPXbRkRYAKWOhwTr5OgbfT43M0WA+eUmPyqYQJn6iS+
   22.76 +75vAUAwNjX/+L0ECYqnnDSb2PPPIdGVSv0wOk01CSLKwlPoq0BezFw4iYqGXcWVN
   22.77 +kKLYvm+o+y6izCOlwtyPZpWDkSb9+gnsRXkjhGAlhVYawYxDWrKJY+9Qk1l7HHFU
   22.78 +45IMaDsiRamgjsmBuSrR95TUsaxwx2+/BXPK/7UmHFSR3JTEhzbaOHiGSrS8JxXm
   22.79 +3dt95pfSnAM5OxcLge6m0tSPXil/2KN/MGoJLR45+hZq9Kh6P4mb4MOu/nrIjq1U
   22.80 +O/haaF7seh1N4CvhFK+0DQ32aMwrgyla/EinRq2uIcXGMXBqf6k3zL8KlAfPWdeR
   22.81 +8uhShYs6HdIN7bG91jy83QTrYfptDBWQUPQdcqaNDb1ByOBpzkbyjrGTszCdYou2
   22.82 +/WZlV3vRuadiK1OfvnWWQrEGX6A4ug3fy6H7rfJmCxqL7w06eac+leihCw1y8rZK
   22.83 +A+Er1smYn5k1A8Jc66QsKlXGWvpTF28nGmKkLHJeQquS2OK4TPKNObY3U1J7MpNj
   22.84 +asAvoiyrQppHKOEqSf9nls2EdywtN45sGaotPZVmNUzSU4xyA4WmJBLScDHysgf/
   22.85 +1ZwaHpexLCUNKd8dQ/dm1SXO0zG0+iB7sDpjPcYUTIzVRLP6ihB+xvQZpd29Z6mG
   22.86 +lM8AcJSaLhl9bFe5PPBKIygtuuj8nJojpY2MlU4jK23axeNvtIFgypZmU8E1gCSj
   22.87 +kxEXuL8cBhF090DJ/xeDtc5hlXi7QXL6p3WnDpSe5W0NT9mI36wg21vlqwVvJVn+
   22.88 ++WKkD4pkAQEaXxa5B7U5XAut43qdQQSWcZHBsfifsYFmwhyT63XkAhkkCg1pTKCI
   22.89 +Lm9W2GN6VBk9gp4fzKEzf29yUjs18xa1g8sYGi9iWMKJVvCpVSVbtl2f6UAkUFky
   22.90 +0H1e1U4sFiQtapTpvnJyyUg4jaOoU9lATID32ZMcxPeLFpPI0k2zFV1j3SqaC67K
   22.91 +MxPzhQhCepq+8T9cdp7fBee6u5DVKEOd6jpdgom7VYE68Hjc7HyWd2XsOyDmGemp
   22.92 +QbPloTJDoa/g1sMbG6AW5zuNNoKlrktAb04S6AQdE30KdivwKtAEg34/rmzOXeNf
   22.93 +Y6L4W7OIPNhrv7uvmiMiLnAKxFBTlru5rPuNzIVmjmuysJBisi+3dqtN+KuZYWAo
   22.94 +C5ssivN+OBuJrypoKOYmyDmmOgT5YRIn7Uhm0DTOez10aprg8jOyfcyCSZ10c633
   22.95 +ZeUNl7FQ2+Nt/yyY3mQH1HP2aU+orA/qpqAYW4kaq8wWH/00soUXrik5FkPg5s5H
   22.96 +Mrqtnz4QimqAMTixQg2BTGATVm+Kv2F9PVlTmiSVl4Uv93t7w5ipoCieuYaVmDjq
   22.97 +KSV8RNbasl/+qwtWK0szEeE/8Tl6ZlKT0/EfMYKMGGPbSKryzmjYrSzXK0rkv56S
   22.98 +b9JqdZ633m6EQIBLzImtZscd11kYuiZynJLmWUW5PbdPqo3OGCIcWuOcQ4aPHVqD
   22.99 +0XPna30bcjIY937Jo5+kWyg2/mLQ24aV99hUIhOc5aLlNi6P5n+22iA68t/sUIT9
  22.100 +v+UC3ScD8MmUQg6gRPt8bWk78DmMP6AmnZx8a0HwCYwPmSi4uZzh1AkREs4KsWHe
  22.101 +z2NqeolSvSH3O3gaWtjs08mPOfZ+JGtDLyfmAM2Ojttfz7gHb6a7ZtjVXgTpXqH7
  22.102 +xGvY3udeibO6THZ9Y9rymXH9OpCt2Qc69GuBAgfDpXZOVb8JMROWnDmgkObo27Kc
  22.103 +bdFSWnzbbWgXo2xVUlKDih3lSaBFdntthAxjKj0dckCJ8J31P+LYBoX9yEeiMZaJ
  22.104 +j1fhiRMk/Ae4hTUbzc0Fabut8A3p0Ah+YgH2Pf7DEr7LE9/GH5/J4hB5fEC+n4Dq
  22.105 +q+fjNkZyvx6seZrwr1h5APg96cmrZeuAELLRkJzqbBq5aaQQgYr/B9tiA+PIIn9p
  22.106 +6grNHm8YKwIzO/Tgk7MgLyEZIkg0CVvM74t6u7JLc+hXoDLe957BrgDuqgwRu8OP
  22.107 +kh2OfFKBAw/38qtDdILpZ4MI4L9OoQI0QNTScN2aB9eXRBir9DvUhAtmNfepQjxM
  22.108 +O/tWO2D+L27Yoofx2LIZ0trg4GcaOSE3jmsHr+VAz9axwVUdG9wQPbSshzbsCpZQ
  22.109 +YXY+o1ofi+RSm957ANUYqSnpRl7PYiypVbdu+wVK+iqacotFeoCDV+vmOtfUkarW
  22.110 +DRNLDCZeguG0zQ5MsGAn1jhxsFXizSoXFlqfHUP3B3qJpP5R4CiFZjdYzXHUwoxl
  22.111 +N0UdleUpq5gWJXpZd+0ELR2HvA7d2NVLjUEgJuyMnwx+lXnqd9v9jdk9SMkHxwje
  22.112 +ETGI+Vy4dpjAGwTQNTUTMD/R4krlJP8uJ4D2mrzK/aFL1+WilKKWIEUlH7llwRT0
  22.113 +IEQplQt/4tXd4sCuojqV6dqJtWEQV0Y51BKDgUL7bTzktCTKCS5LzhxRD/5EtC/R
  22.114 +vYNXyfEvU2j4MxG/ghQwBlFF/v8xrWCufL4Jqr2sx3OWQIkJY5Ol6F3ZjY7amUEt
  22.115 +CMvgkx0cL2YeYejCwLUcgMXKO1FaWfL/DDg0DvOjqhlXWgUXUslDst6lmDZFNiuc
  22.116 +MJJsNyMPCO9o+Y1YCSiXz8M801Md3YsAxv59+1Tlqq1oxkSXOhmpVtKkiQNTjRmH
  22.117 +L9bVjckIJ95ejynGKpjoEPZsXDPBVq1ty59+EXZTVO1ZqxkrcrHFzAtQqkwpHOur
  22.118 +9rd0D26W//PzOGDC30O3VNkhgxtB94bzlXkmg7PleiJBgOrThPM/ojTOQmW3BX4y
  22.119 +EqzSQGJUDErQwOtXBYCJW5K5ITorfi/ykYKaCuj2MfmHFyWTV0kBQh/zOKWXcH70
  22.120 +kfdjDo9Oh7D+RhOsSwrUj0v3t91+x4LcCMsL83vbKqtoYZ1+a7PJl7/zY81Rwuo4
  22.121 +lCx911ITGeHR5nxclHeZ5XRkNjdJVz0UNshRyPbaH7d8XnkJA0ZeKcTJnUEMtjwJ
  22.122 +t5HnJE5aUbilAxBm+3bhmHrmcExXW7OgtbX9Nb8R7Yg7CX6Bgc1t8cRTuGT+sfFC
  22.123 +7jOFijjxNApGQfKC4cuCTx5J6P62FSc=
  22.124 +=orc1
  22.125 +-----END PGP MESSAGE-----
  22.126 +
  22.127 +--2eb141f241b71efb79e2a9e37545e146--