Merged in default ENGINE-398
authorKrista Bennett <krista@pep-project.org>
Thu, 02 Aug 2018 12:20:11 +0200
branchENGINE-398
changeset 2799913e407519e2
parent 2752 713b65791080
parent 2788 bd1e854e98ad
child 2800 2c40068e30a0
Merged in default
src/message_api.c
src/message_api.h
src/pEpEngine.c
src/pEp_internal.h
     1.1 --- a/Makefile.conf	Fri Jun 15 20:17:49 2018 +0200
     1.2 +++ b/Makefile.conf	Thu Aug 02 12:20:11 2018 +0200
     1.3 @@ -115,3 +115,6 @@
     1.4  # Example:
     1.5  #    EXTRA_MACROS=-DDEFAULT_KEYSERVER=\"default-server.org\" -DCRASHDUMP_DEFAULT_LINES=23
     1.6  #EXTRA_MACROS=
     1.7 +
     1.8 +# add this for running tests in debugger
     1.9 +#TEST_DEBUGGER=lldb --batch -o r
     2.1 --- a/default.conf	Fri Jun 15 20:17:49 2018 +0200
     2.2 +++ b/default.conf	Thu Aug 02 12:20:11 2018 +0200
     2.3 @@ -212,7 +212,7 @@
     2.4  ifeq ($(BUILD_FOR),Linux)
     2.5      LIBGPGME=libgpgme.so.11
     2.6  else ifeq ($(BUILD_FOR),Darwin)
     2.7 -    LIBGPGME=libgpgme.dylib
     2.8 +    LIBGPGME=libgpgme.11.dylib
     2.9  endif
    2.10  
    2.11  # libGPGME library search flag
     3.1 --- a/src/message_api.c	Fri Jun 15 20:17:49 2018 +0200
     3.2 +++ b/src/message_api.c	Thu Aug 02 12:20:11 2018 +0200
     3.3 @@ -148,6 +148,43 @@
     3.4      }
     3.5  }
     3.6  
     3.7 +bool _memnmemn(const char* needle, 
     3.8 +                size_t needle_size,
     3.9 +                const char* haystack, 
    3.10 +                size_t haystack_size) 
    3.11 +{
    3.12 +    if (needle_size > haystack_size) {
    3.13 +        return false;
    3.14 +    }
    3.15 +    else if (needle_size == 0) {
    3.16 +        return true;
    3.17 +    }
    3.18 +                        
    3.19 +    bool found = true;
    3.20 +    const char* haystack_ptr = haystack;
    3.21 +    unsigned int i = 0;
    3.22 +    size_t remaining_hay = haystack_size;
    3.23 +    for (i = 0; i < haystack_size && (remaining_hay >= needle_size); i++, haystack_ptr++) {
    3.24 +        found = false;
    3.25 +        const char* needle_ptr = needle;
    3.26 +        if (*haystack_ptr == *needle) {
    3.27 +            const char* haystack_tmp = haystack_ptr;
    3.28 +            unsigned int j;
    3.29 +            found = true;
    3.30 +            for (j = 0; j < needle_size; j++) {
    3.31 +                if (*needle_ptr++ != *haystack_tmp++) {
    3.32 +                    found = false;
    3.33 +                    break;
    3.34 +                }
    3.35 +            }
    3.36 +            if (found)
    3.37 +                break;
    3.38 +        }
    3.39 +        remaining_hay--;
    3.40 +    }
    3.41 +    return found;
    3.42 +}
    3.43 +
    3.44  void add_opt_field(message *msg, const char *name, const char *value)
    3.45  {
    3.46      assert(msg && name && value);
    3.47 @@ -169,7 +206,10 @@
    3.48      }
    3.49  }
    3.50  
    3.51 -void replace_opt_field(message *msg, const char *name, const char *value)
    3.52 +void replace_opt_field(message *msg, 
    3.53 +                       const char *name, 
    3.54 +                       const char *value,
    3.55 +                       bool clobber)
    3.56  {
    3.57      assert(msg && name && value);
    3.58      
    3.59 @@ -189,8 +229,10 @@
    3.60          }
    3.61          
    3.62          if (pair) {
    3.63 -            free(pair->value);
    3.64 -            pair->value = strdup(value);
    3.65 +            if (clobber) {
    3.66 +                free(pair->value);
    3.67 +                pair->value = strdup(value);
    3.68 +            }
    3.69          }
    3.70          else {
    3.71              add_opt_field(msg, name, value);
    3.72 @@ -198,25 +240,25 @@
    3.73      }
    3.74  }
    3.75  
    3.76 -
    3.77  static void decorate_message(
    3.78      message *msg,
    3.79      PEP_rating rating,
    3.80      stringlist_t *keylist,
    3.81 -    bool add_version
    3.82 +    bool add_version,
    3.83 +    bool clobber
    3.84      )
    3.85  {
    3.86      assert(msg);
    3.87  
    3.88      if (add_version)
    3.89 -        replace_opt_field(msg, "X-pEp-Version", PEP_VERSION);
    3.90 +        replace_opt_field(msg, "X-pEp-Version", PEP_VERSION, clobber);
    3.91  
    3.92      if (rating != PEP_rating_undefined)
    3.93 -        replace_opt_field(msg, "X-EncStatus", rating_to_string(rating));
    3.94 +        replace_opt_field(msg, "X-EncStatus", rating_to_string(rating), clobber);
    3.95  
    3.96      if (keylist) {
    3.97          char *_keylist = keylist_to_string(keylist);
    3.98 -        replace_opt_field(msg, "X-KeyList", _keylist);
    3.99 +        replace_opt_field(msg, "X-KeyList", _keylist, clobber);
   3.100          free(_keylist);
   3.101      }
   3.102  }
   3.103 @@ -857,7 +899,7 @@
   3.104  }
   3.105  
   3.106  static message* wrap_message_as_attachment(message* envelope, 
   3.107 -    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
   3.108 +    message* attachment, bool keep_orig_subject) {
   3.109      
   3.110      if (!attachment)
   3.111          return NULL;
   3.112 @@ -866,24 +908,16 @@
   3.113  
   3.114      PEP_STATUS status = PEP_STATUS_OK;
   3.115  
   3.116 -    replace_opt_field(attachment, "X-pEp-Version", PEP_VERSION);
   3.117 +    replace_opt_field(attachment, "X-pEp-Version", PEP_VERSION, true);
   3.118          
   3.119 -    if (!_envelope && (wrap_type != PEP_message_transport)) {
   3.120 +    if (!_envelope) {
   3.121          _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
   3.122          status = generate_message_id(_envelope);
   3.123          
   3.124          if (status != PEP_STATUS_OK)
   3.125              goto enomem;
   3.126          
   3.127 -        const char* inner_type_string = "";
   3.128 -        switch (wrap_type) {
   3.129 -            case PEP_message_key_reset:
   3.130 -                inner_type_string = "KEY_RESET";
   3.131 -                break;
   3.132 -            default:
   3.133 -                inner_type_string = "INNER";
   3.134 -        }
   3.135 -        attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
   3.136 +        attachment->longmsg = encapsulate_message_wrap_info("INNER", attachment->longmsg);
   3.137          _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
   3.138      }
   3.139      else {
   3.140 @@ -1111,18 +1145,18 @@
   3.141          return false;
   3.142  
   3.143      if (strcmp(blob->mime_type, "application/octet-stream") == 0) {
   3.144 -        if (strcmp(ext, ".pgp") == 0 || strcmp(ext, ".gpg") == 0 ||
   3.145 -            strcmp(ext, ".asc") == 0)
   3.146 +        if (strcmp(ext, ".pgp") == 0 || strcmp(ext, ".gpg") == 0)
   3.147              return true;
   3.148      }
   3.149 -    else if (strcmp(blob->mime_type, "text/plain") == 0) {
   3.150 -        if (strcmp(ext, ".asc") == 0) {
   3.151 -            // NOTE: if this ends up being too expensive, we can implement
   3.152 -            // strnstr...
   3.153 -            if (strstr(blob->value, "BEGIN PGP PUBLIC KEY") == NULL &&
   3.154 -                strstr(blob->value, "BEGIN PGP PRIVATE KEY") == NULL)
   3.155 -                return true;
   3.156 -        }
   3.157 +    if (strcmp(ext, ".asc") == 0 && blob->size > 0) {            
   3.158 +        const char* pubk_needle = "BEGIN PGP PUBLIC KEY";
   3.159 +        size_t pubk_needle_size = strlen(pubk_needle);
   3.160 +        const char* privk_needle = "BEGIN PGP PRIVATE KEY";
   3.161 +        size_t privk_needle_size = strlen(privk_needle);
   3.162 +
   3.163 +        if (!(_memnmemn(pubk_needle, pubk_needle_size, blob->value, blob->size)) &&
   3.164 +            !(_memnmemn(privk_needle, privk_needle_size, blob->value, blob->size)))
   3.165 +            return true;
   3.166      }
   3.167  
   3.168      return false;
   3.169 @@ -1374,6 +1408,7 @@
   3.170              bool free_blobval = false;
   3.171              
   3.172              if (is_encrypted_attachment(bl)) {
   3.173 +                    
   3.174                  char* bl_ptext = NULL;
   3.175                  size_t bl_psize = 0;
   3.176                  stringlist_t* bl_keylist = NULL;
   3.177 @@ -1465,48 +1500,6 @@
   3.178      free(revoked_fpr);
   3.179  }
   3.180  
   3.181 -PEP_STATUS create_standalone_key_reset_message(message** dst, 
   3.182 -                                               pEp_identity* recip,
   3.183 -                                               const char* revoke_fpr,
   3.184 -                                               const char* new_fpr) {
   3.185 -                                                   
   3.186 -    if (!dst || !recip->user_id || !recip->address)
   3.187 -        return PEP_ILLEGAL_VALUE;
   3.188 -
   3.189 -    *dst = NULL;
   3.190 -    // Get own identity user has corresponded with
   3.191 -    pEp_identity* own_identity = NULL;
   3.192 -    PEP_STATUS status = get_own_address_for_contact_id(PEP_SESSION session,
   3.193 -                                                       recip,
   3.194 -                                                       &own_identity);                                                       
   3.195 -    if (status != PEP_STATUS_OK)
   3.196 -        return status;
   3.197 -        
   3.198 -    message* reset_message = new_message(PEP_dir_outgoing);
   3.199 -    reset_message->from = own_identity;
   3.200 -    reset_message->to = new_identity_list(identity_dup(recip)); // ?
   3.201 -    
   3.202 -    status = _attach_key(session, revoke_fpr, reset_message);
   3.203 -    if (status != PEP_STATUS_OK)
   3.204 -        goto pep_free;
   3.205 -    status = _attach_key(session, new_fpr, reset_message);
   3.206 -    if (status != PEP_STATUS_OK)
   3.207 -        goto pep_free;
   3.208 -    
   3.209 -    message* output_msg = NULL;
   3.210 -    
   3.211 -    status = encrypt_message(session, reset_message, NULL,
   3.212 -                             output_msg, PEP_enc_PGP_MIME,
   3.213 -                             PEP_encrypt_flag_key_reset_only);
   3.214 -
   3.215 -    if (status == PEP_STATUS_OK)
   3.216 -        *dst = output_msg;
   3.217 -        
   3.218 -pep_free:
   3.219 -    free_message(reset_message);
   3.220 -    return status;
   3.221 -}
   3.222 -
   3.223  PEP_cryptotech determine_encryption_format(message *msg)
   3.224  {
   3.225      assert(msg);
   3.226 @@ -1596,6 +1589,8 @@
   3.227      if (src->enc_format != PEP_enc_none)
   3.228          return PEP_ILLEGAL_VALUE;
   3.229  
   3.230 +    bool force_v_1 = flags & PEP_encrypt_flag_force_version_1;
   3.231 +    
   3.232      *dst = NULL;
   3.233  
   3.234      if (src->from && (!src->from->user_id || src->from->user_id[0] == '\0')) {
   3.235 @@ -1630,6 +1625,7 @@
   3.236  
   3.237      identity_list * _il;
   3.238  
   3.239 +
   3.240      if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
   3.241      {
   3.242          // BCC limited support:
   3.243 @@ -1807,14 +1803,13 @@
   3.244              attach_own_key(session, src);
   3.245              added_key_to_real_src = true;
   3.246          }
   3.247 -        decorate_message(src, PEP_rating_undefined, NULL, true);
   3.248 +        decorate_message(src, PEP_rating_undefined, NULL, true, true);
   3.249          return PEP_UNENCRYPTED;
   3.250      }
   3.251      else {
   3.252          // FIXME - we need to deal with transport types (via flag)
   3.253 -        if ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp) {
   3.254 -            message_wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   3.255 -            _src = wrap_message_as_attachment(NULL, src, message_wrap_type, false);
   3.256 +        if ((!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
   3.257 +            _src = wrap_message_as_attachment(NULL, src, false);
   3.258              if (!_src)
   3.259                  goto pep_error;
   3.260          }
   3.261 @@ -1868,7 +1863,7 @@
   3.262      }
   3.263  
   3.264      if (msg) {
   3.265 -        decorate_message(msg, PEP_rating_undefined, NULL, true);
   3.266 +        decorate_message(msg, PEP_rating_undefined, NULL, true, true);
   3.267          if (_src->id) {
   3.268              msg->id = strdup(_src->id);
   3.269              assert(msg->id);
   3.270 @@ -2058,7 +2053,7 @@
   3.271      }
   3.272              
   3.273      // Ok, it's in there. Let's do this.        
   3.274 -    status = encrypt_message(session, src, keys, dst, enc_format, 0);
   3.275 +    status = encrypt_message(session, src, keys, dst, enc_format, flags);
   3.276      
   3.277      // Delete what we added to src
   3.278      free_bloblist(created_bl);
   3.279 @@ -2111,8 +2106,8 @@
   3.280      determine_encryption_format(src);
   3.281      if (src->enc_format != PEP_enc_none)
   3.282          return PEP_ILLEGAL_VALUE;
   3.283 +
   3.284      if (target_id && (!target_id->user_id || target_id->user_id[0] == '\0')) {
   3.285 -        
   3.286          char* own_id = NULL;
   3.287          status = get_default_own_userid(session, &own_id);
   3.288          if (own_id) {
   3.289 @@ -2155,7 +2150,7 @@
   3.290      // if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   3.291      //     _attach_key(session, target_fpr, src);
   3.292  
   3.293 -    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
   3.294 +    _src = wrap_message_as_attachment(NULL, src, false);
   3.295      if (!_src)
   3.296          goto pep_error;
   3.297  
   3.298 @@ -2197,7 +2192,7 @@
   3.299               if (msg->id == NULL)
   3.300                   goto enomem;
   3.301           }
   3.302 -         decorate_message(msg, PEP_rating_undefined, NULL, true);
   3.303 +         decorate_message(msg, PEP_rating_undefined, NULL, true, true);
   3.304       }
   3.305  
   3.306      *dst = msg;
   3.307 @@ -3027,22 +3022,6 @@
   3.308      return NULL;
   3.309  }
   3.310  
   3.311 -PEP_STATUS check_for_own_revoked_key(
   3.312 -        PEP_SESSION session, 
   3.313 -        stringlist_t* keylist,
   3.314 -        char** bad_fpr,
   3.315 -        char** replacement_fpr
   3.316 -    ) 
   3.317 -{
   3.318 -    if (!session || !bad_fpr || !replacement_fpr)
   3.319 -        return PEP_ILLEGAL_VALUE;
   3.320 -    stringlist_t* _k = keylist;
   3.321 -    while (_k) {
   3.322 -        
   3.323 -    }
   3.324 -}
   3.325 -
   3.326 -
   3.327  DYNAMIC_API PEP_STATUS _decrypt_message(
   3.328          PEP_SESSION session,
   3.329          message *src,
   3.330 @@ -3420,7 +3399,7 @@
   3.331      if (msg) {
   3.332          
   3.333          /* add pEp-related status flags to header */
   3.334 -        decorate_message(msg, *rating, _keylist, false);
   3.335 +        decorate_message(msg, *rating, _keylist, false, false);
   3.336          
   3.337          if (imported_keys)
   3.338              remove_attached_keys(msg);
   3.339 @@ -3433,10 +3412,6 @@
   3.340          }
   3.341      } // End prepare output message for return
   3.342  
   3.343 -    // 3. Check to see if the sender used a bad key
   3.344 -    char* bad_fpr = NULL;
   3.345 -    status = check_for_own_revoked_key(session, _keylist, &bad_fpr);
   3.346 -    
   3.347      *dst = msg;
   3.348      *keylist = _keylist;
   3.349  
     4.1 --- a/src/message_api.h	Fri Jun 15 20:17:49 2018 +0200
     4.2 +++ b/src/message_api.h	Thu Aug 02 12:20:11 2018 +0200
     4.3 @@ -39,7 +39,11 @@
     4.4      // This is only used internally and (eventually) by transport functions
     4.5      PEP_encrypt_flag_inner_message = 0x8,
     4.6      
     4.7 -    PEP_encrypt_flag_key_reset_only = 0x16,
     4.8 +    // This is mainly used by pEp clients to send private keys to 
     4.9 +    // their own PGP-only device
    4.10 +    PEP_encrypt_flag_force_version_1 = 0x16,
    4.11 +    
    4.12 +    PEP_encrypt_flag_key_reset_only = 0x32,
    4.13      
    4.14  } PEP_encrypt_flags; 
    4.15  
    4.16 @@ -278,7 +282,10 @@
    4.17  //      dst (out)           pointer to new decrypted message or NULL on failure
    4.18  //      keylist (inout)     in: stringlist with additional keyids for reencryption if needed
    4.19  //                              (will be freed and replaced with output keylist) 
    4.20 -//                          out: stringlist with keyids
    4.21 +//                          out: stringlist with keyids used for signing and encryption. first
    4.22 +//                               first key is signer, additional keys are the ones it was encrypted
    4.23 +//                               to. Only signer and whichever of the user's keys was used are 
    4.24 +//                               reliable
    4.25  //      rating (out)        rating for the message
    4.26  //      flags (inout)       flags to signal special decryption features
    4.27  //
     5.1 --- a/src/pEpEngine.h	Fri Jun 15 20:17:49 2018 +0200
     5.2 +++ b/src/pEpEngine.h	Thu Aug 02 12:20:11 2018 +0200
     5.3 @@ -300,9 +300,9 @@
     5.4  //
     5.5  //    return value:
     5.6  //        PEP_STATUS_OK = 0            encryption and signing succeeded
     5.7 -//        PEP_KEY_NOT_FOUND            at least one of the receipient keys
     5.8 +//        PEP_KEY_NOT_FOUND            at least one of the recipient keys
     5.9  //                                     could not be found
    5.10 -//        PEP_KEY_HAS_AMBIG_NAME       at least one of the receipient keys has
    5.11 +//        PEP_KEY_HAS_AMBIG_NAME       at least one of the recipient keys has
    5.12  //                                     an ambiguous name
    5.13  //        PEP_GET_KEY_FAILED           cannot retrieve key
    5.14  //
    5.15 @@ -462,7 +462,7 @@
    5.16      PEP_ct_confirmed_encryption = 0x90,         // generic
    5.17      PEP_ct_OpenPGP_weak = 0x91,                 // RSA 1024 is weak (unused)
    5.18  
    5.19 -    PEP_ct_to_be_checked_confirmed = 0xa0,      //generic
    5.20 +    PEP_ct_to_be_checked_confirmed = 0xa0,      // generic
    5.21      PEP_ct_SMIME = 0xa1,
    5.22      PEP_ct_CMS = 0xa2,
    5.23  
     6.1 --- a/src/platform_unix.c	Fri Jun 15 20:17:49 2018 +0200
     6.2 +++ b/src/platform_unix.c	Thu Aug 02 12:20:11 2018 +0200
     6.3 @@ -448,4 +448,5 @@
     6.4          return agent_conf;
     6.5      return NULL;
     6.6  }
     6.7 -#endif
     6.8 \ No newline at end of file
     6.9 +#endif
    6.10 +
     7.1 --- a/src/platform_unix.h	Fri Jun 15 20:17:49 2018 +0200
     7.2 +++ b/src/platform_unix.h	Thu Aug 02 12:20:11 2018 +0200
     7.3 @@ -46,7 +46,11 @@
     7.4  
     7.5  const char *android_system_db(void);
     7.6  #define SYSTEM_DB android_system_db()
     7.7 +#ifdef __APPLE__
     7.8 +#define LIBGPGME "libgpgme.11.dylib"
     7.9 +#else
    7.10  #define LIBGPGME "libgpgme.so"
    7.11 +#endif
    7.12  
    7.13  #elif __APPLE__
    7.14  #include "TargetConditionals.h"
     8.1 --- a/test/Makefile	Fri Jun 15 20:17:49 2018 +0200
     8.2 +++ b/test/Makefile	Thu Aug 02 12:20:11 2018 +0200
     8.3 @@ -17,8 +17,8 @@
     8.4  OBJS := $(addsuffix .o,$(basename $(SRCS)))
     8.5  DEPS := $(OBJS:.o=.d)
     8.6  
     8.7 -INC_DIRS := ./include /usr/local/include  
     8.8 -INC_FLAGS := $(addprefix -I,$(INC_DIRS))
     8.9 +INC_DIRS := ./include /usr/local/include 
    8.10 +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) $(GPGME_INC)
    8.11  
    8.12  LDFLAGS += -L/usr/local/lib
    8.13  
    8.14 @@ -100,7 +100,7 @@
    8.15  test_home_: 
    8.16  	
    8.17  
    8.18 -.PHONY: test_home_
    8.19 +.PHONY: scripts
    8.20  scripts: 
    8.21  ifdef PY_ENV
    8.22  	$(PY_ENV) genscripts.py
    8.23 @@ -108,7 +108,7 @@
    8.24  
    8.25  .PHONY: test
    8.26  test: all
    8.27 -	./$(TARGET)
    8.28 +	$(TEST_DEBUGGER) ./$(TARGET)
    8.29  	
    8.30  .PHONY: clean
    8.31  clean:
     9.1 Binary file test/test_files/427_old_db has changed