I don't even know what has happened on this branch, but it's been done for a while now and merged in, so I hope this fixes it ENGINE-207
authorkrista
Wed, 28 Jun 2017 13:33:53 +0200
branchENGINE-207
changeset 1896bd4d52d8a71f
parent 1893 9e648c792083
parent 1895 fcafaecea8b6
child 1897 b024524a81dc
I don't even know what has happened on this branch, but it's been done for a while now and merged in, so I hope this fixes it
src/message_api.c
     1.1 --- a/.hgignore	Mon May 08 15:48:46 2017 +0200
     1.2 +++ b/.hgignore	Wed Jun 28 13:33:53 2017 +0200
     1.3 @@ -47,10 +47,10 @@
     1.4  *.xml
     1.5  *.dot
     1.6  *.svg
     1.7 -.imported
     1.8  gpg-agent.conf
     1.9  gpg.conf
    1.10  pubring.gpg
    1.11  random_seed
    1.12  secring.gpg
    1.13  trustdb.gpg
    1.14 +.pEp_management.db
     2.1 --- a/Makefile.conf	Mon May 08 15:48:46 2017 +0200
     2.2 +++ b/Makefile.conf	Wed Jun 28 13:33:53 2017 +0200
     2.3 @@ -2,7 +2,7 @@
     2.4  
     2.5  BUILD_ON=$(shell uname)
     2.6  BUILD_FOR=$(BUILD_ON)
     2.7 -OPTIMIZE=-g -Wall -O0 -fPIC
     2.8 +OPTIMIZE=-g -Wall -O0 -fPIC -DDEBUG_ERRORSTACK
     2.9  #OPTIMIZE=-O3 -Wall -DNDEBUG -std=c99
    2.10  LD=$(CC)
    2.11  #CC=gcc-mp-4.9 -std=c99 -fstrict-aliasing -Wstrict-aliasing=3
     3.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon May 08 15:48:46 2017 +0200
     3.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Wed Jun 28 13:33:53 2017 +0200
     3.3 @@ -190,6 +190,7 @@
     3.4  
     3.5  /* Begin PBXFileReference section */
     3.6  		430D258A1C9ED75A00B94535 /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../src/blacklist.c; sourceTree = "<group>"; };
     3.7 +		4346F86A1ECB38E700381CBE /* sync_app.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sync_app.h; path = ../src/sync_app.h; sourceTree = "<group>"; };
     3.8  		4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
     3.9  		4354FF681D6EE1A70033069C /* NULL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NULL.c; path = ../asn.1/NULL.c; sourceTree = "<group>"; };
    3.10  		43BA0F451D7964750059172F /* asn1_helper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn1_helper.c; path = ../src/asn1_helper.c; sourceTree = "<group>"; };
    3.11 @@ -517,6 +518,7 @@
    3.12  				646C41421D510D2C00C63EFF /* sync_send_actions.c */,
    3.13  				646C41431D510D2C00C63EFF /* sync.c */,
    3.14  				646C41441D510D2C00C63EFF /* sync.h */,
    3.15 +				4346F86A1ECB38E700381CBE /* sync_app.h */,
    3.16  				646788871CEB3D120001F54C /* map_asn1.c */,
    3.17  				646788881CEB3D120001F54C /* map_asn1.h */,
    3.18  				430D258A1C9ED75A00B94535 /* blacklist.c */,
    3.19 @@ -779,7 +781,7 @@
    3.20  			);
    3.21  			runOnlyForDeploymentPostprocessing = 0;
    3.22  			shellPath = /bin/sh;
    3.23 -			shellScript = "mkdir -p \"$BUILT_PRODUCTS_DIR/include\"\n\ncp \"$SRCROOT/../src/\"{\\\npEpEngine.h,\\\ncryptotech.h,\\\nkeymanagement.h,\\\nmessage_api.h,\\\ndynamic_api.h,\\\nstringlist.h,\\\ntimestamp.h,\\\nidentity_list.h,\\\nbloblist.h,\\\nstringpair.h,\\\nmessage.h,\\\nmime.h} \"$BUILT_PRODUCTS_DIR/include\"\n\nbash -l -c \"make -C ../asn.1 generate\"\nbash -l -c \"make -C ../asn.1\"\nbash -l -c \"LC_ALL=en_US.UTF-8 YML_PATH=$HOME/yml2 make -C ../sync\"\n";
    3.24 +			shellScript = "mkdir -p \"$BUILT_PRODUCTS_DIR/include\"\n\ncp \"$SRCROOT/../src/\"{\\\npEpEngine.h,\\\ncryptotech.h,\\\nkeymanagement.h,\\\nmessage_api.h,\\\ndynamic_api.h,\\\nstringlist.h,\\\ntimestamp.h,\\\nidentity_list.h,\\\nbloblist.h,\\\nstringpair.h,\\\nmessage.h,\\\nmime.h,\\\nsync_fsm.h,\\\nsync.h,\\\nsync_app.h} \"$BUILT_PRODUCTS_DIR/include\"\n\nbash -l -c \"make -C ../asn.1 generate\"\nbash -l -c \"make -C ../asn.1\"\nbash -l -c \"LC_ALL=en_US.UTF-8 YML_PATH=$HOME/yml2 make -C ../sync\"\n";
    3.25  		};
    3.26  /* End PBXShellScriptBuildPhase section */
    3.27  
     4.1 --- a/db/create_system_db.sql	Mon May 08 15:48:46 2017 +0200
     4.2 +++ b/db/create_system_db.sql	Wed Jun 28 13:33:53 2017 +0200
     4.3 @@ -46,5 +46,8 @@
     4.4  
     4.5  INSERT INTO i18n_language VALUES ('tr', 'Türkçe');
     4.6  INSERT INTO i18n_token VALUES ('tr', 1000, 'Güvenlik kelimelerini Türkçe görüntülemek istiyorum');
     4.7 +
     4.8 +INSERT INTO i18n_language VALUES ('nl', 'Nederlands');
     4.9 +INSERT INTO i18n_token VALUES ('nl', 1000, 'Ik wil de trustwords in de nederlandse taal laten zien');
    4.10  -- add more languages here
    4.11  
     5.1 --- a/src/Makefile	Mon May 08 15:48:46 2017 +0200
     5.2 +++ b/src/Makefile	Wed Jun 28 13:33:53 2017 +0200
     5.3 @@ -93,7 +93,7 @@
     5.4  install: $(TARGET)
     5.5  	cp $< $(PREFIX)/lib/
     5.6  	mkdir -p $(PREFIX)/include/pEp
     5.7 -	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h sync_fsm.h blacklist.h openpgp_compat.h $(PREFIX)/include/pEp/
     5.8 +	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h sync_fsm.h sync_app.h blacklist.h openpgp_compat.h $(PREFIX)/include/pEp/
     5.9  
    5.10  uninstall:
    5.11  	rm -f $(PREFIX)/lib/$(TARGET)
     6.1 --- a/src/keymanagement.c	Mon May 08 15:48:46 2017 +0200
     6.2 +++ b/src/keymanagement.c	Wed Jun 28 13:33:53 2017 +0200
     6.3 @@ -91,7 +91,7 @@
     6.4      assert(!EMPTYSTR(identity->address));
     6.5  
     6.6      if (!(session && identity && !EMPTYSTR(identity->address)))
     6.7 -        return PEP_ILLEGAL_VALUE;
     6.8 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
     6.9  
    6.10      if (identity->me || (identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0)) {
    6.11          identity->me = true;
    6.12 @@ -144,9 +144,23 @@
    6.13  
    6.14          /* if we have a stored_identity fpr */
    6.15          if (!EMPTYSTR(stored_identity->fpr)) {
    6.16 -            status = blacklist_is_listed(session, stored_identity->fpr, &dont_use_stored_fpr);
    6.17 -            if (status != PEP_STATUS_OK)
    6.18 -                dont_use_stored_fpr = true; 
    6.19 +            bool revoked = false;
    6.20 +            status = key_revoked(session, stored_identity->fpr, &revoked);
    6.21 +            
    6.22 +            if (status != PEP_STATUS_OK || revoked)
    6.23 +                dont_use_stored_fpr = true;
    6.24 +                
    6.25 +            if (revoked) {
    6.26 +                // Do stuff
    6.27 +                status = update_trust_for_fpr(session, stored_identity->fpr, PEP_ct_key_revoked);
    6.28 +                // What to do on failure? FIXME
    6.29 +                status = replace_identities_fpr(session, stored_identity->fpr, "");
    6.30 +            }
    6.31 +            else {    
    6.32 +                status = blacklist_is_listed(session, stored_identity->fpr, &dont_use_stored_fpr);
    6.33 +                if (status != PEP_STATUS_OK)
    6.34 +                    dont_use_stored_fpr = true; 
    6.35 +            }
    6.36          }
    6.37              
    6.38  
    6.39 @@ -312,7 +326,7 @@
    6.40      free_identity(stored_identity);
    6.41      free_identity(temp_id);
    6.42      
    6.43 -    return status;
    6.44 +    return ADD_TO_LOG(status);
    6.45  }
    6.46  
    6.47  PEP_STATUS elect_ownkey(
    6.48 @@ -339,19 +353,14 @@
    6.49          for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
    6.50              bool is_own = false;
    6.51              
    6.52 -            if (session->use_only_own_private_keys)
    6.53 -            {
    6.54 -                status = own_key_is_listed(session, _keylist->value, &is_own);
    6.55 -                assert(status == PEP_STATUS_OK);
    6.56 -                if (status != PEP_STATUS_OK) {
    6.57 -                    free_stringlist(keylist);
    6.58 -                    return status;
    6.59 -                }
    6.60 +            status = own_key_is_listed(session, _keylist->value, &is_own);
    6.61 +            assert(status == PEP_STATUS_OK);
    6.62 +            if (status != PEP_STATUS_OK) {
    6.63 +                free_stringlist(keylist);
    6.64 +                return status;
    6.65              }
    6.66 -
    6.67 -            // TODO : also accept synchronized device group keys ?
    6.68              
    6.69 -            if (!session->use_only_own_private_keys || is_own)
    6.70 +            if (is_own)
    6.71              {
    6.72                  PEP_comm_type _comm_type_key;
    6.73                  
    6.74 @@ -407,7 +416,7 @@
    6.75      
    6.76      *is_usable = !dont_use_fpr;
    6.77      
    6.78 -    return status;
    6.79 +    return ADD_TO_LOG(status);
    6.80  }
    6.81  
    6.82  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags)
    6.83 @@ -425,7 +434,7 @@
    6.84      if (!(session && identity && !EMPTYSTR(identity->address) &&
    6.85              (EMPTYSTR(identity->user_id) ||
    6.86              strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
    6.87 -        return PEP_ILLEGAL_VALUE;
    6.88 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
    6.89  
    6.90      identity->comm_type = PEP_ct_pEp;
    6.91      identity->me = true;
    6.92 @@ -513,7 +522,7 @@
    6.93          status = elect_ownkey(session, identity);
    6.94          assert(status == PEP_STATUS_OK);
    6.95          if (status != PEP_STATUS_OK) {
    6.96 -            return status;
    6.97 +            return ADD_TO_LOG(status);
    6.98          }
    6.99  
   6.100          bool has_private = false;
   6.101 @@ -543,27 +552,18 @@
   6.102      {
   6.103          status = key_revoked(session, identity->fpr, &revoked);
   6.104  
   6.105 -        // Forces re-election if key is missing and own-key-only not forced
   6.106 -        if (!session->use_only_own_private_keys && status == PEP_KEY_NOT_FOUND) 
   6.107 +        if (status != PEP_STATUS_OK) 
   6.108          {
   6.109 -            status = elect_ownkey(session, identity);
   6.110 -            assert(status == PEP_STATUS_OK);
   6.111 -            if (status != PEP_STATUS_OK) {
   6.112 -                return status;
   6.113 -            }
   6.114 -        } 
   6.115 -        else if (status != PEP_STATUS_OK) 
   6.116 -        {
   6.117 -            return status;
   6.118 +            return ADD_TO_LOG(status);
   6.119          }
   6.120      }
   6.121     
   6.122      bool new_key_generated = false;
   6.123  
   6.124      if (EMPTYSTR(identity->fpr) || revoked)
   6.125 -    {        
   6.126 +    {
   6.127          if(!do_keygen){
   6.128 -            return PEP_GET_KEY_FAILED;
   6.129 +            return ADD_TO_LOG(PEP_GET_KEY_FAILED);
   6.130          }
   6.131  
   6.132          if(revoked)
   6.133 @@ -581,7 +581,7 @@
   6.134              DEBUG_LOG("generating key pair failed", "debug", buf);
   6.135              if(revoked && r_fpr)
   6.136                  free(r_fpr);
   6.137 -            return status;
   6.138 +            return ADD_TO_LOG(status);
   6.139          }
   6.140  
   6.141          new_key_generated = true;
   6.142 @@ -592,7 +592,7 @@
   6.143                                   identity->fpr, time(NULL));
   6.144              free(r_fpr);
   6.145              if (status != PEP_STATUS_OK) {
   6.146 -                return status;
   6.147 +                return ADD_TO_LOG(status);
   6.148              }
   6.149          }
   6.150      }
   6.151 @@ -605,7 +605,7 @@
   6.152  
   6.153          assert(status == PEP_STATUS_OK);
   6.154          if (status != PEP_STATUS_OK) {
   6.155 -            return status;
   6.156 +            return ADD_TO_LOG(status);
   6.157          }
   6.158  
   6.159          if (status == PEP_STATUS_OK && expired) {
   6.160 @@ -633,12 +633,12 @@
   6.161          }
   6.162      }
   6.163  
   6.164 -    return PEP_STATUS_OK;
   6.165 +    return ADD_TO_LOG(PEP_STATUS_OK);
   6.166  }
   6.167  
   6.168  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
   6.169  {
   6.170 -    return _myself(session, identity, true, false);
   6.171 +    return ADD_TO_LOG(_myself(session, identity, true, false));
   6.172  }
   6.173  
   6.174  DYNAMIC_API PEP_STATUS register_examine_function(
   6.175 @@ -1010,7 +1010,7 @@
   6.176      return _own_keys_retrieve(session, keylist, 0);
   6.177  }
   6.178  
   6.179 -// TODO: Unused for now, but should be used when sync receive old keys (ENGINE-145)
   6.180 +// FIXME: should it be be used when sync receive old keys ? (ENGINE-145)
   6.181  DYNAMIC_API PEP_STATUS set_own_key(
   6.182         PEP_SESSION session,
   6.183         const char *address,
   6.184 @@ -1020,12 +1020,12 @@
   6.185      PEP_STATUS status = PEP_STATUS_OK;
   6.186      
   6.187      assert(session &&
   6.188 -           address && address[0] &&
   6.189 +           address &&
   6.190             fpr && fpr[0]
   6.191            );
   6.192      
   6.193      if (!(session &&
   6.194 -          address && address[0] &&
   6.195 +          address &&
   6.196            fpr && fpr[0]
   6.197           ))
   6.198          return PEP_ILLEGAL_VALUE;
     7.1 --- a/src/keymanagement.h	Mon May 08 15:48:46 2017 +0200
     7.2 +++ b/src/keymanagement.h	Wed Jun 28 13:33:53 2017 +0200
     7.3 @@ -15,6 +15,11 @@
     7.4  //      session (in)        session to use
     7.5  //      identity (inout)    identity information of communication partner
     7.6  //                          (identity->fpr is OUT ONLY)
     7.7 +//  return value:
     7.8 +//      PEP_STATUS_OK if identity could be updated,
     7.9 +//      PEP_GET_KEY_FAILED for own identity that must be completed (myself())
    7.10 +//      any other value on error
    7.11 +//
    7.12  //  caveat:
    7.13  //      if this function returns PEP_ct_unknown or PEP_ct_key_expired in
    7.14  //      identity->comm_type, the caller must insert the identity into the
    7.15 @@ -159,7 +164,6 @@
    7.16          pEp_identity *ident
    7.17      );
    7.18  
    7.19 -
    7.20  // own_key_is_listed() - returns true id key is listed as own key
    7.21  //
    7.22  //  parameters:
    7.23 @@ -235,7 +239,12 @@
    7.24          stringlist_t **keylist
    7.25        );
    7.26  
    7.27 +DYNAMIC_API PEP_STATUS set_own_key(
    7.28 +       PEP_SESSION session,
    7.29 +       const char *address,
    7.30 +       const char *fpr
    7.31 +    );
    7.32 +
    7.33  #ifdef __cplusplus
    7.34  }
    7.35  #endif
    7.36 -
     8.1 --- a/src/message_api.c	Mon May 08 15:48:46 2017 +0200
     8.2 +++ b/src/message_api.c	Wed Jun 28 13:33:53 2017 +0200
     8.3 @@ -169,19 +169,22 @@
     8.4                      goto enomem;
     8.5              }
     8.6          }
     8.7 +        *shortmsg = _shortmsg;
     8.8      }
     8.9      else {
    8.10 -        _shortmsg = strdup("");
    8.11 -        assert(_shortmsg);
    8.12 -        if (_shortmsg == NULL)
    8.13 -            goto enomem;
    8.14 +        // If there's no "Subject: " and the shortmsg is
    8.15 +        // pEp (or anything else), then we shouldn't be replacing it.
    8.16 +        // Chances are that the message wasn't encrypted
    8.17 +        // using pEp and that the actually subject IS pEp. In any event,
    8.18 +        // erasing the subject line when we don't have one in the plaintext
    8.19 +        // isn't the right behaviour.
    8.20 +        // _shortmsg = strdup("");
    8.21          _longmsg = strdup(src);
    8.22          assert(_longmsg);
    8.23          if (_longmsg == NULL)
    8.24              goto enomem;
    8.25      }
    8.26 -
    8.27 -    *shortmsg = _shortmsg;
    8.28 +    
    8.29      *longmsg = _longmsg;
    8.30  
    8.31      return 0;
    8.32 @@ -823,69 +826,61 @@
    8.33  
    8.34  
    8.35      PEP_comm_type bare_comm_type = PEP_ct_unknown;
    8.36 +    PEP_comm_type resulting_comm_type = PEP_ct_unknown;
    8.37      PEP_STATUS status = get_key_rating(session, fpr, &bare_comm_type);
    8.38      if (status != PEP_STATUS_OK)
    8.39          return PEP_rating_undefined;
    8.40  
    8.41 -    PEP_comm_type least_trust_type = PEP_ct_unknown;
    8.42 -    least_trust(session, fpr, &least_trust_type);
    8.43 -
    8.44 -    if (least_trust_type == PEP_ct_unknown) {
    8.45 -        return _rating(bare_comm_type, PEP_rating_undefined);
    8.46 +    PEP_comm_type least_comm_type = PEP_ct_unknown;
    8.47 +    least_trust(session, fpr, &least_comm_type);
    8.48 +
    8.49 +    if (least_comm_type == PEP_ct_unknown) {
    8.50 +        resulting_comm_type = bare_comm_type;
    8.51 +    } else if (least_comm_type < PEP_ct_strong_but_unconfirmed ||
    8.52 +               bare_comm_type < PEP_ct_strong_but_unconfirmed) {
    8.53 +        // take minimum if anything bad
    8.54 +        resulting_comm_type = least_comm_type < bare_comm_type ? 
    8.55 +                              least_comm_type : 
    8.56 +                              bare_comm_type;
    8.57      } else {
    8.58 -        return _rating(least_trust_type, PEP_rating_undefined);
    8.59 +        resulting_comm_type = least_comm_type;
    8.60      }
    8.61 +    return _rating(resulting_comm_type, PEP_rating_undefined);
    8.62  }
    8.63  
    8.64  static PEP_rating worst_rating(PEP_rating rating1, PEP_rating rating2) {
    8.65      return ((rating1 < rating2) ? rating1 : rating2);
    8.66  }
    8.67  
    8.68 -static PEP_rating keylist_rating(PEP_SESSION session, stringlist_t *keylist)
    8.69 +static PEP_rating keylist_rating(PEP_SESSION session, stringlist_t *keylist, char* sender_fpr, PEP_rating sender_rating)
    8.70  {
    8.71 -    PEP_rating rating = PEP_rating_undefined;
    8.72 +    PEP_rating rating = sender_rating;
    8.73  
    8.74      assert(keylist && keylist->value);
    8.75      if (keylist == NULL || keylist->value == NULL)
    8.76          return PEP_rating_undefined;
    8.77  
    8.78      stringlist_t *_kl;
    8.79 -    bool first = true;
    8.80      for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
    8.81 -        PEP_comm_type ct;
    8.82 -        PEP_STATUS status;
    8.83 +
    8.84 +        // Ignore own fpr
    8.85 +        if(_same_fpr(sender_fpr, strlen(sender_fpr), _kl->value, strlen(_kl->value)))
    8.86 +            continue;
    8.87  
    8.88          PEP_rating _rating_ = key_rating(session, _kl->value);
    8.89           
    8.90          if (_rating_ <= PEP_rating_mistrust)
    8.91              return _rating_;
    8.92              
    8.93 -        if (first) {
    8.94 -            rating = _rating_;
    8.95 -            first = false;
    8.96 -        }
    8.97 -        else if (rating == PEP_rating_undefined)
    8.98 -            rating = worst_rating(rating, _rating_);
    8.99 -
   8.100 -        if (_rating_ >= PEP_rating_reliable) {
   8.101 -            status = least_trust(session, _kl->value, &ct);
   8.102 -            if (status != PEP_STATUS_OK)
   8.103 -                return PEP_rating_undefined;
   8.104 -            if (ct == PEP_ct_unknown){
   8.105 -                /* per edouard, we reduce reliable+ ratings to reliable because
   8.106 -                   ct unknown */
   8.107 -                if (rating >= PEP_rating_reliable){
   8.108 -                    rating = PEP_rating_reliable; 
   8.109 -                }
   8.110 -            }
   8.111 -            else{
   8.112 -                rating = worst_rating(rating, _rating(ct, rating));
   8.113 -            }
   8.114 -        }
   8.115 -        else if (_rating_ == PEP_rating_unencrypted) {
   8.116 +        if (_rating_ == PEP_rating_unencrypted)
   8.117 +        {
   8.118              if (rating > PEP_rating_unencrypted_for_some)
   8.119                  rating = worst_rating(rating, PEP_rating_unencrypted_for_some);
   8.120          }
   8.121 +        else
   8.122 +        {
   8.123 +            rating = worst_rating(rating, _rating_);
   8.124 +        }
   8.125      }
   8.126  
   8.127      return rating;
   8.128 @@ -992,8 +987,13 @@
   8.129          if (bl && bl->value && bl->size && bl->size < MAX_KEY_SIZE
   8.130                  && is_key(bl))
   8.131          {
   8.132 -            import_key(session, bl->value, bl->size, private_idents);
   8.133 +            identity_list *local_private_idents = NULL;
   8.134 +            import_key(session, bl->value, bl->size, &local_private_idents);
   8.135              remove = true;
   8.136 +            if (private_idents && *private_idents == NULL && local_private_idents != NULL)
   8.137 +                *private_idents = local_private_idents;
   8.138 +            else
   8.139 +                free_identity_list(local_private_idents);
   8.140          }
   8.141      }
   8.142      return remove;
   8.143 @@ -1101,20 +1101,20 @@
   8.144      assert(enc_format != PEP_enc_none);
   8.145  
   8.146      if (!(session && src && dst && enc_format != PEP_enc_none))
   8.147 -        return PEP_ILLEGAL_VALUE;
   8.148 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.149  
   8.150      if (src->dir == PEP_dir_incoming)
   8.151 -        return PEP_ILLEGAL_VALUE;
   8.152 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.153  
   8.154      determine_encryption_format(src);
   8.155      if (src->enc_format != PEP_enc_none)
   8.156 -        return PEP_ILLEGAL_VALUE;
   8.157 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.158  
   8.159      *dst = NULL;
   8.160  
   8.161      status = myself(session, src->from);
   8.162      if (status != PEP_STATUS_OK)
   8.163 -        goto pep_error;
   8.164 +        GOTO(pep_error);
   8.165  
   8.166      keys = new_stringlist(src->from->fpr);
   8.167      if (keys == NULL)
   8.168 @@ -1148,7 +1148,7 @@
   8.169          PEP_STATUS _status = update_identity(session, _il->ident);
   8.170          if (_status != PEP_STATUS_OK) {
   8.171              status = _status;
   8.172 -            goto pep_error;
   8.173 +            GOTO(pep_error);
   8.174          }
   8.175  
   8.176          if (_il->ident->fpr && _il->ident->fpr[0]) {
   8.177 @@ -1169,7 +1169,7 @@
   8.178              PEP_STATUS _status = update_identity(session, _il->ident);
   8.179              if (_status != PEP_STATUS_OK) {
   8.180                  status = _status;
   8.181 -                goto pep_error;
   8.182 +                GOTO(pep_error);
   8.183              }
   8.184  
   8.185              if (_il->ident->fpr && _il->ident->fpr[0]) {
   8.186 @@ -1190,7 +1190,7 @@
   8.187              if (_status != PEP_STATUS_OK)
   8.188              {
   8.189                  status = _status;
   8.190 -                goto pep_error;
   8.191 +                GOTO(pep_error);
   8.192              }
   8.193  
   8.194              if (_il->ident->fpr && _il->ident->fpr[0]) {
   8.195 @@ -1215,7 +1215,7 @@
   8.196          free_stringlist(keys);
   8.197          if (!session->passive_mode && !(flags & PEP_encrypt_flag_force_no_attached_key))
   8.198              attach_own_key(session, src);
   8.199 -        return PEP_UNENCRYPTED;
   8.200 +        return ADD_TO_LOG(PEP_UNENCRYPTED);
   8.201      }
   8.202      else {
   8.203          msg = clone_to_empty_message(src);
   8.204 @@ -1242,14 +1242,14 @@
   8.205          default:
   8.206              assert(0);
   8.207              status = PEP_ILLEGAL_VALUE;
   8.208 -            goto pep_error;
   8.209 +            GOTO(pep_error);
   8.210          }
   8.211  
   8.212          if (status == PEP_OUT_OF_MEMORY)
   8.213              goto enomem;
   8.214  
   8.215          if (status != PEP_STATUS_OK)
   8.216 -            goto pep_error;
   8.217 +            GOTO(pep_error);
   8.218      }
   8.219  
   8.220      free_stringlist(keys);
   8.221 @@ -1272,7 +1272,7 @@
   8.222      }
   8.223  
   8.224      *dst = msg;
   8.225 -    return status;
   8.226 +    return ADD_TO_LOG(status);
   8.227  
   8.228  enomem:
   8.229      status = PEP_OUT_OF_MEMORY;
   8.230 @@ -1281,7 +1281,7 @@
   8.231      free_stringlist(keys);
   8.232      free_message(msg);
   8.233  
   8.234 -    return status;
   8.235 +    return ADD_TO_LOG(status);
   8.236  }
   8.237  
   8.238  DYNAMIC_API PEP_STATUS encrypt_message_for_self(
   8.239 @@ -1303,18 +1303,18 @@
   8.240      assert(enc_format != PEP_enc_none);
   8.241  
   8.242      if (!(session && src && dst && enc_format != PEP_enc_none))
   8.243 -        return PEP_ILLEGAL_VALUE;
   8.244 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.245  
   8.246      if (src->dir == PEP_dir_incoming)
   8.247 -        return PEP_ILLEGAL_VALUE;
   8.248 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.249  
   8.250      determine_encryption_format(src);
   8.251      if (src->enc_format != PEP_enc_none)
   8.252 -        return PEP_ILLEGAL_VALUE;
   8.253 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.254  
   8.255      status = myself(session, target_id);
   8.256      if (status != PEP_STATUS_OK)
   8.257 -        goto pep_error;
   8.258 +        GOTO(pep_error);
   8.259  
   8.260      *dst = NULL;
   8.261  
   8.262 @@ -1391,7 +1391,7 @@
   8.263      free_stringlist(keys);
   8.264      free_message(msg);
   8.265  
   8.266 -    return status;
   8.267 +    return ADD_TO_LOG(status);
   8.268  }
   8.269  
   8.270  static bool is_a_pEpmessage(const message *msg)
   8.271 @@ -1420,7 +1420,7 @@
   8.272                  && src->from->comm_type != PEP_ct_pEp)
   8.273          {
   8.274              src->from->comm_type |= PEP_ct_pEp_unconfirmed;
   8.275 -            status = update_identity(session, src->from);
   8.276 +            status = set_identity(session, src->from);
   8.277          }
   8.278          return status;
   8.279      }
   8.280 @@ -1503,9 +1503,10 @@
   8.281      if (!end_boundary)
   8.282          return PEP_UNKNOWN_ERROR;
   8.283  
   8.284 -    end_boundary--; // See RFC3156 section 5...
   8.285 -	if (*(end_boundary - 1) == '\r')
   8.286 -		end_boundary--;
   8.287 +    // See RFC3156 section 5...
   8.288 +    end_boundary--; 
   8.289 +    if (*(end_boundary - 1) == '\r')
   8.290 +        end_boundary--; 
   8.291  
   8.292      *ssize = end_boundary - start_boundary;
   8.293      *stext = start_boundary;
   8.294 @@ -1591,6 +1592,46 @@
   8.295      return status;
   8.296  }
   8.297  
   8.298 +PEP_STATUS amend_rating_according_to_sender_and_recipients(
   8.299 +    PEP_SESSION session,
   8.300 +    PEP_rating *rating,
   8.301 +    pEp_identity *sender,
   8.302 +    stringlist_t *recipients) {
   8.303 +    
   8.304 +    PEP_STATUS status = PEP_STATUS_OK;
   8.305 +
   8.306 +    if (*rating > PEP_rating_mistrust) {
   8.307 +
   8.308 +        if (recipients == NULL) {
   8.309 +            *rating = PEP_rating_undefined;
   8.310 +            return PEP_STATUS_OK;
   8.311 +        }
   8.312 +
   8.313 +        char *fpr = recipients->value;
   8.314 +
   8.315 +        if (!(sender && sender->user_id && sender->user_id[0] && fpr && fpr[0])) {
   8.316 +            *rating = PEP_rating_unreliable;
   8.317 +        }
   8.318 +        else {
   8.319 +            pEp_identity *_sender = new_identity(sender->address, fpr,
   8.320 +                                               sender->user_id, sender->username);
   8.321 +            if (_sender == NULL)
   8.322 +                return PEP_OUT_OF_MEMORY;
   8.323 +
   8.324 +            status = get_trust(session, _sender);
   8.325 +            if (_sender->comm_type != PEP_ct_unknown) {
   8.326 +                *rating = keylist_rating(session, recipients, 
   8.327 +                            fpr, _rating(_sender->comm_type, 
   8.328 +                                          PEP_rating_undefined));
   8.329 +            }
   8.330 +            free_identity(_sender);
   8.331 +            if (status == PEP_CANNOT_FIND_IDENTITY)
   8.332 +               status = PEP_STATUS_OK;
   8.333 +        }
   8.334 +    }
   8.335 +    return status;
   8.336 +}
   8.337 +
   8.338  
   8.339  DYNAMIC_API PEP_STATUS _decrypt_message(
   8.340          PEP_SESSION session,
   8.341 @@ -1619,7 +1660,7 @@
   8.342      assert(flags);
   8.343  
   8.344      if (!(session && src && dst && keylist && rating && flags))
   8.345 -        return PEP_ILLEGAL_VALUE;
   8.346 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.347  
   8.348      *flags = 0;
   8.349  
   8.350 @@ -1630,7 +1671,7 @@
   8.351      // we would need to check signature
   8.352      status = _update_identity_for_incoming_message(session, src);
   8.353      if(status != PEP_STATUS_OK)
   8.354 -        return status;
   8.355 +        return ADD_TO_LOG(status);
   8.356  
   8.357      // Get detached signature, if any
   8.358      bloblist_t* detached_sig = NULL;
   8.359 @@ -1664,7 +1705,7 @@
   8.360                                  PEP_decrypt_flag_consume;
   8.361                  }
   8.362                  else if (status != PEP_STATUS_OK) {
   8.363 -                    return status;
   8.364 +                    return ADD_TO_LOG(status);
   8.365                  }
   8.366              }
   8.367              
   8.368 @@ -1696,7 +1737,7 @@
   8.369                  }
   8.370              }
   8.371              
   8.372 -            return PEP_UNENCRYPTED;
   8.373 +            return ADD_TO_LOG(PEP_UNENCRYPTED);
   8.374  
   8.375          case PEP_enc_PGP_MIME:
   8.376              ctext = src->attachments->next->value;
   8.377 @@ -1720,7 +1761,7 @@
   8.378                                                     csize, dsig_text, dsig_size,
   8.379                                                     &ptext, &psize, &_keylist);
   8.380      if (status > PEP_CANNOT_DECRYPT_UNKNOWN){
   8.381 -        goto pep_error;
   8.382 +        GOTO(pep_error);
   8.383      }
   8.384  
   8.385      decrypt_status = status;
   8.386 @@ -1896,7 +1937,9 @@
   8.387              case PEP_enc_PGP_MIME_Outlook1:
   8.388                  status = copy_fields(msg, src);
   8.389                  if (status != PEP_STATUS_OK)
   8.390 -                    goto pep_error;
   8.391 +                {
   8.392 +                    GOTO(pep_error);
   8.393 +                }
   8.394  
   8.395                  if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   8.396                  {
   8.397 @@ -1905,9 +1948,24 @@
   8.398  
   8.399                      int r = separate_short_and_long(msg->longmsg, &shortmsg,
   8.400                              &longmsg);
   8.401 +                    
   8.402                      if (r == -1)
   8.403                          goto enomem;
   8.404  
   8.405 +                    if (shortmsg == NULL) {
   8.406 +                        if (src->shortmsg == NULL)
   8.407 +                            shortmsg = strdup("");
   8.408 +                        else {
   8.409 +                            // FIXME: is msg->shortmsg always a copy of
   8.410 +                            // src->shortmsg already?
   8.411 +                            // if so, we need to change the logic so
   8.412 +                            // that in this case, we don't free msg->shortmsg
   8.413 +                            // and do this strdup, etc.
   8.414 +                            shortmsg = strdup(src->shortmsg);
   8.415 +                        }
   8.416 +                    }
   8.417 +
   8.418 +
   8.419                      free(msg->shortmsg);
   8.420                      free(msg->longmsg);
   8.421  
   8.422 @@ -1954,7 +2012,9 @@
   8.423  
   8.424              status = _update_identity_for_incoming_message(session, src);
   8.425              if(status != PEP_STATUS_OK)
   8.426 -                goto pep_error;
   8.427 +            {
   8.428 +                GOTO(pep_error);
   8.429 +            }
   8.430  
   8.431              char *re_ptext = NULL;
   8.432              size_t re_psize;
   8.433 @@ -1968,50 +2028,22 @@
   8.434              free(re_ptext);
   8.435  
   8.436              if (status > PEP_CANNOT_DECRYPT_UNKNOWN)
   8.437 -                goto pep_error;
   8.438 +            {
   8.439 +                GOTO(pep_error);
   8.440 +            }
   8.441  
   8.442              decrypt_status = status;
   8.443          }
   8.444  
   8.445          *rating = decrypt_rating(decrypt_status);
   8.446  
   8.447 -        if (*rating > PEP_rating_mistrust) {
   8.448 -            PEP_rating kl_rating = PEP_rating_undefined;
   8.449 -
   8.450 -            if (_keylist)
   8.451 -                kl_rating = keylist_rating(session, _keylist);
   8.452 -
   8.453 -            if (kl_rating <= PEP_rating_mistrust) {
   8.454 -                *rating = kl_rating;
   8.455 -            }
   8.456 -            else if (*rating >= PEP_rating_reliable &&
   8.457 -                     kl_rating < PEP_rating_reliable) {
   8.458 -                *rating = PEP_rating_unreliable;
   8.459 -            }
   8.460 -            else if (*rating >= PEP_rating_reliable &&
   8.461 -                     kl_rating >= PEP_rating_reliable) {
   8.462 -                if (!(src->from && src->from->user_id && src->from->user_id[0])) {
   8.463 -                    *rating = PEP_rating_unreliable;
   8.464 -                }
   8.465 -                else {
   8.466 -                    char *fpr = _keylist->value;
   8.467 -                    pEp_identity *_from = new_identity(src->from->address, fpr,
   8.468 -                                                       src->from->user_id, src->from->username);
   8.469 -                    if (_from == NULL)
   8.470 -                        goto enomem;
   8.471 -                    status = get_trust(session, _from);
   8.472 -                    if (_from->comm_type != PEP_ct_unknown) {
   8.473 -                        *rating = worst_rating(_rating(_from->comm_type, PEP_rating_undefined),
   8.474 -                                  kl_rating);
   8.475 -                    }
   8.476 -                    free_identity(_from);
   8.477 -                    if (status == PEP_CANNOT_FIND_IDENTITY)
   8.478 -                       status = PEP_STATUS_OK;
   8.479 -                    if (status != PEP_STATUS_OK)
   8.480 -                        goto pep_error;
   8.481 -                }
   8.482 -            }
   8.483 -        }
   8.484 +        status = amend_rating_according_to_sender_and_recipients(session,
   8.485 +                                                                 rating,
   8.486 +                                                                 src->from,
   8.487 +                                                                 _keylist);
   8.488 +
   8.489 +        if (status != PEP_STATUS_OK)
   8.490 +            GOTO(pep_error);
   8.491      }
   8.492      else
   8.493      {
   8.494 @@ -2047,7 +2079,6 @@
   8.495                              PEP_decrypt_flag_ignore :
   8.496                              PEP_decrypt_flag_consume;
   8.497  
   8.498 -                status = decrypt_status;
   8.499              }
   8.500              else if (status != PEP_STATUS_OK){
   8.501                  goto pep_error;
   8.502 @@ -2066,7 +2097,10 @@
   8.503      *dst = msg;
   8.504      *keylist = _keylist;
   8.505  
   8.506 -    return status;
   8.507 +    if(decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   8.508 +        return ADD_TO_LOG(PEP_STATUS_OK);
   8.509 +    else
   8.510 +        return ADD_TO_LOG(decrypt_status);
   8.511  
   8.512  enomem:
   8.513      status = PEP_OUT_OF_MEMORY;
   8.514 @@ -2076,7 +2110,7 @@
   8.515      free_message(msg);
   8.516      free_stringlist(_keylist);
   8.517  
   8.518 -    return status;
   8.519 +    return ADD_TO_LOG(status);
   8.520  }
   8.521  
   8.522  DYNAMIC_API PEP_STATUS decrypt_message(
   8.523 @@ -2125,8 +2159,7 @@
   8.524  
   8.525      free_identity_list(private_il);
   8.526  
   8.527 -    return status;
   8.528 -
   8.529 +    return ADD_TO_LOG(status);
   8.530  }
   8.531  
   8.532  static void _max_comm_type_from_identity_list(
   8.533 @@ -2167,10 +2200,10 @@
   8.534      assert(rating);
   8.535  
   8.536      if (!(session && msg && rating))
   8.537 -        return PEP_ILLEGAL_VALUE;
   8.538 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.539  
   8.540      if (msg->dir != PEP_dir_outgoing)
   8.541 -        return PEP_ILLEGAL_VALUE;
   8.542 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   8.543  
   8.544      *rating = PEP_rating_undefined;
   8.545  
   8.546 @@ -2254,7 +2287,75 @@
   8.547  
   8.548      // this should never happen
   8.549      assert(false);
   8.550 -	return PEP_color_no_color;
   8.551 +    return PEP_color_no_color;
   8.552 +}
   8.553 +
   8.554 +/* [0-9]: 0x30 - 0x39; [A-F] = 0x41 - 0x46; [a-f] = 0x61 - 0x66 */
   8.555 +static short asciihex_to_num(char a) {
   8.556 +    short conv_num = -1;
   8.557 +    if (a >= 0x30 && a <= 0x39)
   8.558 +        conv_num = a - 0x30;
   8.559 +    else {
   8.560 +        // convert case, subtract offset, get number
   8.561 +        conv_num = ((a | 0x20) - 0x61) + 10;
   8.562 +        if (conv_num < 0xa || conv_num > 0xf)
   8.563 +            conv_num = -1;
   8.564 +    }
   8.565 +    return conv_num;
   8.566 +}
   8.567 +
   8.568 +static char num_to_asciihex(short h) {
   8.569 +    if (h < 0 || h > 16)
   8.570 +        return '\0';
   8.571 +    if (h < 10)
   8.572 +        return (char)(h + 0x30);
   8.573 +    return (char)((h - 10) + 0x41); // for readability
   8.574 +}
   8.575 +
   8.576 +static char xor_hex_chars(char a, char b) {
   8.577 +    short a_num = asciihex_to_num(a);
   8.578 +    short b_num = asciihex_to_num(b);
   8.579 +    if (a_num < 0 || b_num < 0)
   8.580 +        return '\0';
   8.581 +    short xor_num = a_num^b_num;
   8.582 +    return num_to_asciihex(xor_num);
   8.583 +}
   8.584 +
   8.585 +static char* skip_separators(char* current, char* begin) {
   8.586 +    while (current >= begin) {
   8.587 +        /* .:,;-_ ' ' - [2c-2e] [3a-3b] [20] [5f] */
   8.588 +        char check_char = *current;
   8.589 +        switch (check_char) {
   8.590 +            case '.':
   8.591 +            case ':':
   8.592 +            case ',':
   8.593 +            case ';':
   8.594 +            case '-':
   8.595 +            case '_':
   8.596 +            case ' ':
   8.597 +                current--;
   8.598 +                continue;
   8.599 +            default:
   8.600 +                break;
   8.601 +        }
   8.602 +        break;
   8.603 +    }
   8.604 +    return current;
   8.605 +}
   8.606 +
   8.607 +PEP_STATUS check_for_zero_fpr(char* fpr) {
   8.608 +    PEP_STATUS status = PEP_TRUSTWORDS_DUPLICATE_FPR;
   8.609 +    
   8.610 +    while (*fpr) {
   8.611 +        if (*fpr != '0') {
   8.612 +            status = PEP_STATUS_OK;
   8.613 +            break;
   8.614 +        }
   8.615 +        fpr++;    
   8.616 +    }
   8.617 +    
   8.618 +    return status;
   8.619 +    
   8.620  }
   8.621  
   8.622  DYNAMIC_API PEP_STATUS get_trustwords(
   8.623 @@ -2270,96 +2371,114 @@
   8.624      assert(words);
   8.625      assert(wsize);
   8.626  
   8.627 +    int SHORT_NUM_TWORDS = 5; 
   8.628 +    
   8.629 +    PEP_STATUS status = PEP_STATUS_OK;
   8.630 +    
   8.631      if (!(session && id1 && id2 && words && wsize) ||
   8.632          !(id1->fpr) || (!id2->fpr))
   8.633          return PEP_ILLEGAL_VALUE;
   8.634  
   8.635 -    const char *source1 = id1->fpr;
   8.636 -    const char *source2 = id2->fpr;
   8.637 -
   8.638 -    *words = NULL;
   8.639 +    char *source1 = id1->fpr;
   8.640 +    char *source2 = id2->fpr;
   8.641 +
   8.642 +    int source1_len = strlen(source1);
   8.643 +    int source2_len = strlen(source2);
   8.644 +    int max_len;
   8.645 +        
   8.646 +    *words = NULL;    
   8.647      *wsize = 0;
   8.648  
   8.649 -    const size_t SHORT_NUM_TWORDS = 5;
   8.650 -
   8.651 -    // N.B. THIS will have to be changed once we start checking trustword entropy.
   8.652 -    // For now, full is ALL, and otherwise it's 5-per-id.
   8.653 -    size_t max_words_per_id = (full ? 0 : SHORT_NUM_TWORDS);
   8.654 -
   8.655 -    char* first_set = NULL;
   8.656 -    char* second_set = NULL;
   8.657 -    size_t first_wsize = 0;
   8.658 -    size_t second_wsize = 0;
   8.659 -
   8.660 -    int fpr_comparison = -255;
   8.661 -    PEP_STATUS status = _compare_fprs(source1, strlen(source1), source2, strlen(source2), &fpr_comparison);
   8.662 -    if (status != PEP_STATUS_OK)
   8.663 -        return status;
   8.664 -
   8.665 -    char* _retstr = NULL;
   8.666 -
   8.667 -    switch (fpr_comparison) {
   8.668 -        case 1: // source1 > source2
   8.669 -            status = trustwords(session, source2, lang, &first_set, &first_wsize, max_words_per_id);
   8.670 -            if (status != PEP_STATUS_OK)
   8.671 -                goto error_release;
   8.672 -            status = trustwords(session, source1, lang, &second_set, &second_wsize, max_words_per_id);
   8.673 -            if (status != PEP_STATUS_OK)
   8.674 -                goto error_release;
   8.675 +    max_len = (source1_len > source2_len ? source1_len : source2_len);
   8.676 +    
   8.677 +    char* XORed_fpr = (char*)(calloc(1,max_len + 1));
   8.678 +    *(XORed_fpr + max_len) = '\0';
   8.679 +    char* result_curr = XORed_fpr + max_len - 1;
   8.680 +    char* source1_curr = source1 + source1_len - 1;
   8.681 +    char* source2_curr = source2 + source2_len - 1;
   8.682 +
   8.683 +    while (source1 <= source1_curr && source2 <= source2_curr) {
   8.684 +        source1_curr = skip_separators(source1_curr, source1);
   8.685 +        source2_curr = skip_separators(source2_curr, source2);
   8.686 +        
   8.687 +        if (source1_curr < source1 || source2_curr < source2)
   8.688              break;
   8.689 -        case 0:
   8.690 -        case -1: // source1 <= source2
   8.691 -            status = trustwords(session, source1, lang, &first_set, &first_wsize, max_words_per_id);
   8.692 -            if (status != PEP_STATUS_OK)
   8.693 -                goto error_release;
   8.694 -            status = trustwords(session, source2, lang, &second_set, &second_wsize, max_words_per_id);
   8.695 -            if (status != PEP_STATUS_OK)
   8.696 -                goto error_release;
   8.697 -            break;
   8.698 -        default:
   8.699 -            return PEP_UNKNOWN_ERROR; // shouldn't be possible
   8.700 -    }
   8.701 -
   8.702 -    size_t _wsize = first_wsize + second_wsize;
   8.703 -
   8.704 -    bool needs_space = (first_set[first_wsize - 1] != ' ');
   8.705 -
   8.706 -    if (needs_space)
   8.707 -        _wsize++;
   8.708 -
   8.709 -    _retstr = calloc(1, _wsize + 1);
   8.710 -
   8.711 -    size_t len = strlcpy(_retstr, first_set, _wsize);
   8.712 -    if (len >= _wsize) {
   8.713 -        status = PEP_UNKNOWN_ERROR;
   8.714 -        goto error_release;
   8.715 -    }
   8.716 -    if (needs_space) {
   8.717 -        strlcat(_retstr, " ", _wsize);
   8.718 -        if (len >= _wsize) {
   8.719 -            status = PEP_UNKNOWN_ERROR;
   8.720 +            
   8.721 +        char xor_hex = xor_hex_chars(*source1_curr, *source2_curr);
   8.722 +        if (xor_hex == '\0') {
   8.723 +            status = PEP_ILLEGAL_VALUE;
   8.724              goto error_release;
   8.725          }
   8.726 +        
   8.727 +        *result_curr = xor_hex;
   8.728 +        result_curr--; source1_curr--; source2_curr--;
   8.729      }
   8.730 -    strlcat(_retstr, second_set, _wsize);
   8.731 -    if (len >= _wsize){
   8.732 -        status = PEP_UNKNOWN_ERROR;
   8.733 +
   8.734 +    char* remainder_start = NULL;
   8.735 +    char* remainder_curr = NULL;
   8.736 +    
   8.737 +    if (source1 <= source1_curr) {
   8.738 +        remainder_start = source1;
   8.739 +        remainder_curr = source1_curr;
   8.740 +    }
   8.741 +    else if (source2 <= source2_curr) {
   8.742 +        remainder_start = source2;
   8.743 +        remainder_curr = source2_curr;
   8.744 +    }
   8.745 +    if (remainder_curr) {
   8.746 +        while (remainder_start <= remainder_curr) {
   8.747 +            remainder_curr = skip_separators(remainder_curr, remainder_start);
   8.748 +            
   8.749 +            if (remainder_curr < remainder_start)
   8.750 +                break;
   8.751 +            
   8.752 +            char the_char = *remainder_curr;
   8.753 +            
   8.754 +            if (asciihex_to_num(the_char) < 0) {
   8.755 +                status = PEP_ILLEGAL_VALUE;
   8.756 +                goto error_release;
   8.757 +            }
   8.758 +            
   8.759 +            *result_curr = the_char;                
   8.760 +            result_curr--;
   8.761 +            remainder_curr--;
   8.762 +        }
   8.763 +    }
   8.764 +    
   8.765 +    result_curr++;
   8.766 +
   8.767 +    if (result_curr > XORed_fpr) {
   8.768 +        char* tempstr = strdup(result_curr);
   8.769 +        free(XORed_fpr);
   8.770 +        XORed_fpr = tempstr;
   8.771 +    }
   8.772 +    
   8.773 +    status = check_for_zero_fpr(XORed_fpr);
   8.774 +    
   8.775 +    if (status != PEP_STATUS_OK)
   8.776          goto error_release;
   8.777 -    }
   8.778 -
   8.779 -    *words = _retstr;
   8.780 -    *wsize = _wsize;
   8.781 +    
   8.782 +    size_t max_words_per_id = (full ? 0 : SHORT_NUM_TWORDS);
   8.783 +
   8.784 +    char* the_words = NULL;
   8.785 +    size_t the_size = 0;
   8.786 +
   8.787 +    status = trustwords(session, XORed_fpr, lang, &the_words, &the_size, max_words_per_id);
   8.788 +    if (status != PEP_STATUS_OK)
   8.789 +        goto error_release;
   8.790 +
   8.791 +    *words = the_words;
   8.792 +    *wsize = the_size;
   8.793 +    
   8.794      status = PEP_STATUS_OK;
   8.795  
   8.796      goto the_end;
   8.797  
   8.798      error_release:
   8.799 -    free(_retstr);
   8.800 -
   8.801 +        free (XORed_fpr);
   8.802 +        
   8.803      the_end:
   8.804 -    free(first_set);
   8.805 -    free(second_set);
   8.806 -    return status;
   8.807 +    return ADD_TO_LOG(status);
   8.808  }
   8.809  
   8.810  DYNAMIC_API PEP_STATUS get_message_trustwords(
   8.811 @@ -2445,7 +2564,7 @@
   8.812  
   8.813      if (status != PEP_STATUS_OK) {
   8.814          free_identity(partner);
   8.815 -        return status;
   8.816 +        return ADD_TO_LOG(status);
   8.817      }
   8.818     
   8.819      // Find own identity corresponding to given account address.
   8.820 @@ -2458,7 +2577,7 @@
   8.821  
   8.822      if (status != PEP_STATUS_OK) {
   8.823          free_identity(stored_identity);
   8.824 -        return status;
   8.825 +        return ADD_TO_LOG(status);
   8.826      }
   8.827  
   8.828      // get the trustwords
   8.829 @@ -2467,7 +2586,7 @@
   8.830                              partner, received_by, 
   8.831                              lang, words, &wsize, full);
   8.832  
   8.833 -    return status;
   8.834 +    return ADD_TO_LOG(status);
   8.835  }
   8.836  
   8.837  DYNAMIC_API PEP_STATUS MIME_decrypt_message(
   8.838 @@ -2489,10 +2608,11 @@
   8.839      PEP_STATUS status = PEP_STATUS_OK;
   8.840      message* tmp_msg = NULL;
   8.841      message* dec_msg = NULL;
   8.842 +    *mime_plaintext = NULL;
   8.843  
   8.844      status = mime_decode_message(mimetext, size, &tmp_msg);
   8.845      if (status != PEP_STATUS_OK)
   8.846 -        goto pep_error;
   8.847 +        GOTO(pep_error);
   8.848  
   8.849      PEP_STATUS decrypt_status = decrypt_message(session,
   8.850                                                  tmp_msg,
   8.851 @@ -2505,17 +2625,10 @@
   8.852          dec_msg = message_dup(tmp_msg);
   8.853      }
   8.854          
   8.855 -    if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN)
   8.856 +    if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN || !dec_msg)
   8.857      {
   8.858          status = decrypt_status;
   8.859 -        goto pep_error;
   8.860 -    }
   8.861 -
   8.862 -    assert(dec_msg);
   8.863 -    
   8.864 -    if (!dec_msg) {
   8.865 -        status = PEP_UNKNOWN_ERROR;
   8.866 -        goto pep_error;
   8.867 +        GOTO(pep_error);
   8.868      }
   8.869  
   8.870      status = mime_encode_message(dec_msg, false, mime_plaintext);
   8.871 @@ -2524,14 +2637,14 @@
   8.872      {
   8.873          free(tmp_msg);
   8.874          free(dec_msg);
   8.875 -        return decrypt_status;
   8.876 +        return ADD_TO_LOG(decrypt_status);
   8.877      }
   8.878      
   8.879  pep_error:
   8.880      free_message(tmp_msg);
   8.881      free_message(dec_msg);
   8.882  
   8.883 -    return status;
   8.884 +    return ADD_TO_LOG(status);
   8.885  }
   8.886  
   8.887  
   8.888 @@ -2551,7 +2664,7 @@
   8.889  
   8.890      status = mime_decode_message(mimetext, size, &tmp_msg);
   8.891      if (status != PEP_STATUS_OK)
   8.892 -        goto pep_error;
   8.893 +        GOTO(pep_error);
   8.894  
   8.895      // This isn't incoming, though... so we need to reverse the direction
   8.896      tmp_msg->dir = PEP_dir_outgoing;
   8.897 @@ -2562,12 +2675,12 @@
   8.898                               enc_format,
   8.899                               flags);
   8.900      if (status != PEP_STATUS_OK)
   8.901 -        goto pep_error;
   8.902 +        GOTO(pep_error);
   8.903  
   8.904  
   8.905      if (!enc_msg) {
   8.906          status = PEP_UNKNOWN_ERROR;
   8.907 -        goto pep_error;
   8.908 +        GOTO(pep_error);
   8.909      }
   8.910  
   8.911      status = mime_encode_message(enc_msg, false, mime_ciphertext);
   8.912 @@ -2576,7 +2689,7 @@
   8.913      free_message(tmp_msg);
   8.914      free_message(enc_msg);
   8.915  
   8.916 -    return status;
   8.917 +    return ADD_TO_LOG(status);
   8.918  
   8.919  }
   8.920  
   8.921 @@ -2620,5 +2733,145 @@
   8.922      free_message(tmp_msg);
   8.923      free_message(enc_msg);
   8.924  
   8.925 -    return status;
   8.926 +    return ADD_TO_LOG(status);
   8.927  }
   8.928 +
   8.929 +static PEP_rating string_to_rating(const char * rating)
   8.930 +{
   8.931 +    if (rating == NULL)
   8.932 +        return PEP_rating_undefined;
   8.933 +    if (strcmp(rating, "cannot_decrypt") == 0)
   8.934 +        return PEP_rating_cannot_decrypt;
   8.935 +    if (strcmp(rating, "have_no_key") == 0)
   8.936 +        return PEP_rating_have_no_key;
   8.937 +    if (strcmp(rating, "unencrypted") == 0)
   8.938 +        return PEP_rating_unencrypted;
   8.939 +    if (strcmp(rating, "unencrypted_for_some") == 0)
   8.940 +        return PEP_rating_unencrypted_for_some;
   8.941 +    if (strcmp(rating, "unreliable") == 0)
   8.942 +        return PEP_rating_unreliable;
   8.943 +    if (strcmp(rating, "reliable") == 0)
   8.944 +        return PEP_rating_reliable;
   8.945 +    if (strcmp(rating, "trusted") == 0)
   8.946 +        return PEP_rating_trusted;
   8.947 +    if (strcmp(rating, "trusted_and_anonymized") == 0)
   8.948 +        return PEP_rating_trusted_and_anonymized;
   8.949 +    if (strcmp(rating, "fully_anonymous") == 0)
   8.950 +        return PEP_rating_fully_anonymous;
   8.951 +    if (strcmp(rating, "mistrust") == 0)
   8.952 +        return PEP_rating_mistrust;
   8.953 +    if (strcmp(rating, "b0rken") == 0)
   8.954 +        return PEP_rating_b0rken;
   8.955 +    if (strcmp(rating, "under_attack") == 0)
   8.956 +        return PEP_rating_under_attack;
   8.957 +    return PEP_rating_undefined;
   8.958 +}
   8.959 +
   8.960 +static PEP_STATUS string_to_keylist(const char * skeylist, stringlist_t **keylist)
   8.961 +{
   8.962 +    if (skeylist == NULL || keylist == NULL)
   8.963 +        return PEP_ILLEGAL_VALUE;
   8.964 +
   8.965 +    stringlist_t *rkeylist = NULL;
   8.966 +    stringlist_t *_kcurr = NULL;
   8.967 +    const char * fpr_begin = skeylist;
   8.968 +    const char * fpr_end = NULL;
   8.969 +
   8.970 +    do {
   8.971 +        fpr_end = strstr(fpr_begin, ",");
   8.972 +        
   8.973 +        char * fpr = strndup(
   8.974 +            fpr_begin,
   8.975 +            (fpr_end == NULL) ? strlen(fpr_begin) : fpr_end - fpr_begin);
   8.976 +        
   8.977 +        if (fpr == NULL)
   8.978 +            goto enomem;
   8.979 +        
   8.980 +        _kcurr = stringlist_add(_kcurr, fpr);
   8.981 +        if (_kcurr == NULL) {
   8.982 +            free(fpr);
   8.983 +            goto enomem;
   8.984 +        }
   8.985 +        
   8.986 +        if (rkeylist == NULL)
   8.987 +            rkeylist = _kcurr;
   8.988 +        
   8.989 +        fpr_begin = fpr_end ? fpr_end + 1 : NULL;
   8.990 +        
   8.991 +    } while (fpr_begin);
   8.992 +    
   8.993 +    *keylist = rkeylist;
   8.994 +    return PEP_STATUS_OK;
   8.995 +    
   8.996 +enomem:
   8.997 +    free_stringlist(rkeylist);
   8.998 +    return PEP_OUT_OF_MEMORY;
   8.999 +}
  8.1000 +
  8.1001 +DYNAMIC_API PEP_STATUS re_evaluate_message_rating(
  8.1002 +    PEP_SESSION session,
  8.1003 +    message *msg,
  8.1004 +    stringlist_t *x_keylist,
  8.1005 +    PEP_rating x_enc_status,
  8.1006 +    PEP_rating *rating
  8.1007 +)
  8.1008 +{
  8.1009 +    PEP_STATUS status = PEP_STATUS_OK;
  8.1010 +    stringlist_t *_keylist = x_keylist;
  8.1011 +    bool must_free_keylist = false;
  8.1012 +    PEP_rating _rating;
  8.1013 +
  8.1014 +    assert(session);
  8.1015 +    assert(msg);
  8.1016 +    assert(rating);
  8.1017 +
  8.1018 +    if (!(session && msg && rating))
  8.1019 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
  8.1020 +
  8.1021 +    *rating = PEP_rating_undefined;
  8.1022 +
  8.1023 +    if (x_enc_status == PEP_rating_undefined){
  8.1024 +        for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
  8.1025 +            if (strcasecmp(i->value->key, "X-EncStatus") == 0){
  8.1026 +                x_enc_status = string_to_rating(i->value->value);
  8.1027 +                goto got_rating;
  8.1028 +            }
  8.1029 +        }
  8.1030 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
  8.1031 +    }
  8.1032 +
  8.1033 +got_rating:
  8.1034 +
  8.1035 +    _rating = x_enc_status;
  8.1036 +
  8.1037 +    if (_keylist == NULL){
  8.1038 +        for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
  8.1039 +            if (strcasecmp(i->value->key, "X-KeyList") == 0){
  8.1040 +                status = string_to_keylist(i->value->value, &_keylist);
  8.1041 +                if (status != PEP_STATUS_OK)
  8.1042 +                    GOTO(pep_error);
  8.1043 +                must_free_keylist = true;
  8.1044 +                goto got_keylist;
  8.1045 +            }
  8.1046 +        }
  8.1047 +        return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
  8.1048 +    }
  8.1049 +got_keylist:
  8.1050 +
  8.1051 +    status = update_identity(session, msg->from);
  8.1052 +    if (status != PEP_STATUS_OK)
  8.1053 +        GOTO(pep_error);
  8.1054 +
  8.1055 +    status = amend_rating_according_to_sender_and_recipients(session,
  8.1056 +                                                             &_rating,
  8.1057 +                                                             msg->from,
  8.1058 +                                                             _keylist);
  8.1059 +    if (status == PEP_STATUS_OK)
  8.1060 +        *rating = _rating;
  8.1061 +    
  8.1062 +pep_error:
  8.1063 +    if (must_free_keylist)
  8.1064 +        free_stringlist(_keylist);
  8.1065 +
  8.1066 +    return ADD_TO_LOG(status);
  8.1067 +}
     9.1 --- a/src/message_api.h	Mon May 08 15:48:46 2017 +0200
     9.2 +++ b/src/message_api.h	Wed Jun 28 13:33:53 2017 +0200
     9.3 @@ -18,8 +18,11 @@
     9.4          const message *msg,
     9.5          identity_list **private_idents
     9.6      );
     9.7 +
     9.8  void attach_own_key(PEP_SESSION session, message *msg);
     9.9 +
    9.10  PEP_cryptotech determine_encryption_format(message *msg);
    9.11 +
    9.12  void add_opt_field(message *msg, const char *name, const char *value);
    9.13  
    9.14  typedef enum _PEP_encrypt_flags {
    9.15 @@ -35,6 +38,7 @@
    9.16  
    9.17  typedef unsigned int PEP_encrypt_flags_t;
    9.18  
    9.19 +
    9.20  // encrypt_message() - encrypt message in memory
    9.21  //
    9.22  //  parameters:
    9.23 @@ -47,16 +51,18 @@
    9.24  //
    9.25  //  return value:
    9.26  //      PEP_STATUS_OK                   on success
    9.27 -//		PEP_KEY_NOT_FOUND	            at least one of the receipient keys
    9.28 -//		                                could not be found
    9.29 -//		PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    9.30 -//		                                an ambiguous name
    9.31 -//		PEP_GET_KEY_FAILED		        cannot retrieve key
    9.32 +//      PEP_KEY_NOT_FOUND               at least one of the receipient keys
    9.33 +//                                      could not be found
    9.34 +//      PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    9.35 +//                                      an ambiguous name
    9.36 +//      PEP_GET_KEY_FAILED              cannot retrieve key
    9.37 +//      PEP_UNENCRYPTED                 no recipients with usable key, 
    9.38 +//                                      message is left unencrypted,
    9.39 +//                                      and key is attached to it
    9.40  //
    9.41 -//	caveat:
    9.42 -//	    the ownershop of src remains with the caller
    9.43 -//	    the ownership of dst goes to the caller
    9.44 -
    9.45 +//  caveat:
    9.46 +//      the ownershop of src remains with the caller
    9.47 +//      the ownership of dst goes to the caller
    9.48  DYNAMIC_API PEP_STATUS encrypt_message(
    9.49          PEP_SESSION session,
    9.50          message *src,
    9.51 @@ -66,6 +72,7 @@
    9.52          PEP_encrypt_flags_t flags
    9.53      );
    9.54  
    9.55 +
    9.56  // encrypt_message_for_self() - encrypt message in memory for user's identity only,
    9.57  //                              ignoring recipients and other identities from
    9.58  //                              the message
    9.59 @@ -78,20 +85,19 @@
    9.60  //      flags (in)          flags to set special encryption features
    9.61  //
    9.62  //  return value:       (FIXME: This may not be correct or complete)
    9.63 -//      PEP_STATUS_OK                   on success
    9.64 -//		PEP_KEY_NOT_FOUND	            at least one of the receipient keys
    9.65 -//		                                could not be found
    9.66 -//		PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    9.67 -//		                                an ambiguous name
    9.68 -//		PEP_GET_KEY_FAILED		        cannot retrieve key
    9.69 +//      PEP_STATUS_OK            on success
    9.70 +//      PEP_KEY_NOT_FOUND        at least one of the receipient keys
    9.71 +//                               could not be found
    9.72 +//      PEP_KEY_HAS_AMBIG_NAME   at least one of the receipient keys has
    9.73 +//                               an ambiguous name
    9.74 +//      PEP_GET_KEY_FAILED       cannot retrieve key
    9.75  //
    9.76 -//	caveat:
    9.77 -//	    the ownership of src remains with the caller
    9.78 +//  caveat:
    9.79 +//      the ownership of src remains with the caller
    9.80  //      the ownership of target_id remains w/ caller            
    9.81 -//	    the ownership of dst goes to the caller
    9.82 +//      the ownership of dst goes to the caller
    9.83  //      message is NOT encrypted for identities other than the target_id (and then,
    9.84 -//          only if the target_id refers to self!)
    9.85 -
    9.86 +//      only if the target_id refers to self!)
    9.87  DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    9.88          PEP_SESSION session,
    9.89          pEp_identity* target_id,
    9.90 @@ -101,6 +107,7 @@
    9.91          PEP_encrypt_flags_t flags
    9.92      );
    9.93  
    9.94 +
    9.95  // MIME_encrypt_message() - encrypt a MIME message, with MIME output
    9.96  //
    9.97  //  parameters:
    9.98 @@ -124,7 +131,6 @@
    9.99  //  caveat:
   9.100  //      the encrypted, encoded mime text will go to the ownership of the caller; mimetext
   9.101  //      will remain in the ownership of the caller
   9.102 -
   9.103  DYNAMIC_API PEP_STATUS MIME_encrypt_message(
   9.104      PEP_SESSION session,
   9.105      const char *mimetext,
   9.106 @@ -135,12 +141,13 @@
   9.107      PEP_encrypt_flags_t flags
   9.108  );
   9.109  
   9.110 +
   9.111  // MIME_encrypt_message_for_self() - encrypt MIME message for user's identity only,
   9.112  //                              ignoring recipients and other identities from
   9.113  //                              the message, with MIME output
   9.114  //  parameters:
   9.115  //      session (in)            session handle
   9.116 -//      target_id (in)      self identity this message should be encrypted for
   9.117 +//      target_id (in)          self identity this message should be encrypted for
   9.118  //      mimetext (in)           MIME encoded text to encrypt
   9.119  //      size (in)               size of input mime text
   9.120  //      mime_ciphertext (out)   encrypted, encoded message
   9.121 @@ -159,7 +166,6 @@
   9.122  //  caveat:
   9.123  //      the encrypted, encoded mime text will go to the ownership of the caller; mimetext
   9.124  //      will remain in the ownership of the caller
   9.125 -
   9.126  DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
   9.127      PEP_SESSION session,
   9.128      pEp_identity* target_id,
   9.129 @@ -171,7 +177,6 @@
   9.130  );
   9.131  
   9.132  
   9.133 -
   9.134  typedef enum _PEP_rating {
   9.135      PEP_rating_undefined = 0,
   9.136      PEP_rating_cannot_decrypt,
   9.137 @@ -196,13 +201,13 @@
   9.138      PEP_color_red = -1,
   9.139  } PEP_color;
   9.140  
   9.141 +
   9.142  // color_from_rating - calculate color from rating
   9.143  //
   9.144  //  parameters:
   9.145  //      rating (in)         rating
   9.146  //
   9.147  //  return value:           color representing that rating
   9.148 -
   9.149  DYNAMIC_API PEP_color color_from_rating(PEP_rating rating);
   9.150  
   9.151  typedef enum _PEP_decrypt_flags {
   9.152 @@ -213,6 +218,7 @@
   9.153  
   9.154  typedef unsigned int PEP_decrypt_flags_t;
   9.155  
   9.156 +
   9.157  // decrypt_message() - decrypt message in memory
   9.158  //
   9.159  //  parameters:
   9.160 @@ -224,15 +230,16 @@
   9.161  //      flags (out)         flags to signal special decryption features
   9.162  //
   9.163  //  return value:
   9.164 -//      error status or PEP_STATUS_OK on success
   9.165 +//      error status 
   9.166 +//      or PEP_DECRYPTED if message decrypted but not verified
   9.167 +//      or PEP_STATUS_OK on success
   9.168  //
   9.169 -//	caveat:
   9.170 -//	    the ownership of src remains with the caller
   9.171 -//	    the ownership of dst goes to the caller
   9.172 -//	    the ownership of keylist goes to the caller
   9.173 -//	    if src is unencrypted this function returns PEP_UNENCRYPTED and sets
   9.174 -//	    dst to NULL
   9.175 -
   9.176 +// caveat:
   9.177 +//      the ownership of src remains with the caller
   9.178 +//      the ownership of dst goes to the caller
   9.179 +//      the ownership of keylist goes to the caller
   9.180 +//      if src is unencrypted this function returns PEP_UNENCRYPTED and sets
   9.181 +//      dst to NULL
   9.182  DYNAMIC_API PEP_STATUS decrypt_message(
   9.183          PEP_SESSION session,
   9.184          message *src,
   9.185 @@ -242,6 +249,7 @@
   9.186          PEP_decrypt_flags_t *flags
   9.187  );
   9.188  
   9.189 +
   9.190  // MIME_decrypt_message() - decrypt a MIME message, with MIME output
   9.191  //
   9.192  //  parameters:
   9.193 @@ -267,7 +275,6 @@
   9.194  //  caveat:
   9.195  //      the decrypted, encoded mime text will go to the ownership of the caller; mimetext
   9.196  //      will remain in the ownership of the caller
   9.197 -
   9.198  DYNAMIC_API PEP_STATUS MIME_decrypt_message(
   9.199      PEP_SESSION session,
   9.200      const char *mimetext,
   9.201 @@ -295,17 +302,17 @@
   9.202  //  return value:
   9.203  //      error status or PEP_STATUS_OK on success
   9.204  //
   9.205 -//	caveat:
   9.206 -//	    the ownership of msg remains with the caller
   9.207 -//	    the ownership of ident goes to the caller
   9.208 -//	    msg MUST be encrypted so that this function can check own signature
   9.209 -
   9.210 +//  caveat:
   9.211 +//      the ownership of msg remains with the caller
   9.212 +//      the ownership of ident goes to the caller
   9.213 +//      msg MUST be encrypted so that this function can check own signature
   9.214  DYNAMIC_API PEP_STATUS own_message_private_key_details(
   9.215          PEP_SESSION session,
   9.216          message *msg,
   9.217          pEp_identity **ident 
   9.218  );
   9.219  
   9.220 +
   9.221  // outgoing_message_rating() - get rating for an outgoing message
   9.222  //
   9.223  //  parameters:
   9.224 @@ -320,7 +327,6 @@
   9.225  //      msg->from must point to a valid pEp_identity
   9.226  //      msg->dir must be PEP_dir_outgoing
   9.227  //      the ownership of msg remains with the caller
   9.228 -
   9.229  DYNAMIC_API PEP_STATUS outgoing_message_rating(
   9.230          PEP_SESSION session,
   9.231          message *msg,
   9.232 @@ -340,7 +346,6 @@
   9.233  //
   9.234  //  caveat:
   9.235  //      the ownership of ident remains with the caller
   9.236 -
   9.237  DYNAMIC_API PEP_STATUS identity_rating(
   9.238          PEP_SESSION session,
   9.239          pEp_identity *ident,
   9.240 @@ -356,6 +361,7 @@
   9.241  //                          **path is owned by the library, do not change it!
   9.242  DYNAMIC_API PEP_STATUS get_binary_path(PEP_cryptotech tech, const char **path);
   9.243  
   9.244 +
   9.245  // get_trustwords() - get full trustwords string for a *pair* of identities
   9.246  //
   9.247  //    parameters:
   9.248 @@ -381,12 +387,12 @@
   9.249  //        the word pointer goes to the ownership of the caller
   9.250  //        the caller is responsible to free() it (on Windoze use pEp_free())
   9.251  //
   9.252 -
   9.253  DYNAMIC_API PEP_STATUS get_trustwords(
   9.254      PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
   9.255      const char* lang, char **words, size_t *wsize, bool full
   9.256  );
   9.257  
   9.258 +
   9.259  // get_message_trustwords() - get full trustwords string for message sender and reciever identities 
   9.260  //
   9.261  //    parameters:
   9.262 @@ -422,6 +428,35 @@
   9.263      const char* lang, char **words, bool full
   9.264  );
   9.265  
   9.266 +// re_evaluate_message_rating() - re-evaluate already decrypted message rating
   9.267 +//
   9.268 +//  parameters:
   9.269 +//      session (in)            session handle
   9.270 +//      msg (in)                message to get the rating for
   9.271 +//      x_keylist (in)          decrypted message recipients keys fpr
   9.272 +//      x_enc_status (in)       original rating for the decrypted message
   9.273 +//      rating (out)            rating for the message
   9.274 +//
   9.275 +//  return value:
   9.276 +//      PEP_ILLEGAL_VALUE       if decrypted message doesn't contain 
   9.277 +//                              X-EncStatus optional field and x_enc_status is 
   9.278 +//                              pEp_rating_udefined
   9.279 +//                              or if decrypted message doesn't contain 
   9.280 +//                              X-Keylist optional field and x_keylist is NULL
   9.281 +//      PEP_OUT_OF_MEMORY       if not enough memory could be allocated
   9.282 +//
   9.283 +//  caveat:
   9.284 +//      msg->from must point to a valid pEp_identity
   9.285 +//      the ownership of msg remains with the caller
   9.286 +//	    the ownership of x_keylist remains with to the caller
   9.287 +
   9.288 +DYNAMIC_API PEP_STATUS re_evaluate_message_rating(
   9.289 +    PEP_SESSION session,
   9.290 +    message *msg,
   9.291 +    stringlist_t *x_keylist,
   9.292 +    PEP_rating x_enc_status,
   9.293 +    PEP_rating *rating
   9.294 +);
   9.295  #ifdef __cplusplus
   9.296  }
   9.297  #endif
    10.1 --- a/src/pEpEngine.c	Mon May 08 15:48:46 2017 +0200
    10.2 +++ b/src/pEpEngine.c	Wed Jun 28 13:33:53 2017 +0200
    10.3 @@ -10,6 +10,32 @@
    10.4  
    10.5  static int init_count = -1;
    10.6  
    10.7 +// sql overloaded functions - modified from sqlite3.c
    10.8 +static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    10.9 +    char *z1;
   10.10 +    const char *z2;
   10.11 +    int i, n;
   10.12 +    z2 = (char*)sqlite3_value_text(argv[0]);
   10.13 +    n = sqlite3_value_bytes(argv[0]);
   10.14 +    /* Verify that the call to _bytes() does not invalidate the _text() pointer */
   10.15 +    assert( z2==(char*)sqlite3_value_text(argv[0]) );
   10.16 +    if( z2 ){
   10.17 +        z1 = (char*)sqlite3_malloc(n+1);
   10.18 +        if( z1 ){
   10.19 +            for(i=0; i<n; i++){
   10.20 +                char c = z2[i];
   10.21 +                char c_mod = c | 0x20;
   10.22 +                if (c_mod < 0x61 || c_mod > 0x7a)
   10.23 +                    c_mod = c;
   10.24 +                z1[i] = c_mod;
   10.25 +            }
   10.26 +            z1[n] = '\0';
   10.27 +            sqlite3_result_text(ctx, z1, n, sqlite3_free);
   10.28 +        }
   10.29 +    }
   10.30 +}
   10.31 +
   10.32 +
   10.33  // sql manipulation statements
   10.34  static const char *sql_log = 
   10.35      "insert into log (title, entity, description, comment)"
   10.36 @@ -19,6 +45,7 @@
   10.37      "select id, word from wordlist where lang = lower(?1) "
   10.38      "and id = ?2 ;";
   10.39  
   10.40 +
   10.41  static const char *sql_get_identity =  
   10.42      "select fpr, username, comm_type, lang,"
   10.43      "   identity.flags | pgp_keypair.flags"
   10.44 @@ -26,8 +53,18 @@
   10.45      "   join person on id = identity.user_id"
   10.46      "   join pgp_keypair on fpr = identity.main_key_id"
   10.47      "   join trust on id = trust.user_id"
   10.48 -    "       and pgp_keypair_fpr = identity.main_key_id"
   10.49 -    "   where address = ?1 and identity.user_id = ?2;";
   10.50 +    "       and pgp_keypair_fpr = identity.main_key_id"    
   10.51 +    "   where (case when (address = ?1) then (1)"
   10.52 +    "               when (lower(address) = lower(?1)) then (1)"
   10.53 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   10.54 +    "               else 0"
   10.55 +    "          end) = 1"
   10.56 +    "   and identity.user_id = ?2;";
   10.57 +
   10.58 +static const char *sql_replace_identities_fpr =  
   10.59 +    "update identity"
   10.60 +    "   set main_key_id = ?1 "
   10.61 +    "   where main_key_id = ?2 ;";
   10.62  
   10.63  // Set person, but if already exist, only update.
   10.64  // if main_key_id already set, don't touch.
   10.65 @@ -85,6 +122,11 @@
   10.66      "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
   10.67      "values (?1, upper(replace(?2,' ','')), ?3) ;";
   10.68  
   10.69 +static const char *sql_update_trust_for_fpr =
   10.70 +    "update trust "
   10.71 +    "set comm_type = ?1 "
   10.72 +    "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   10.73 +
   10.74  static const char *sql_get_trust = 
   10.75      "select comm_type from trust where user_id = ?1 "
   10.76      "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   10.77 @@ -136,7 +178,11 @@
   10.78      " union "
   10.79      "  select main_key_id from identity "
   10.80      "   where main_key_id = upper(replace(?1,' ',''))"
   10.81 -    "    and user_id = '" PEP_OWN_USERID "' );";
   10.82 +    "    and user_id = '" PEP_OWN_USERID "' "
   10.83 +    " union "
   10.84 +    "  select fpr from own_keys "
   10.85 +    "   where fpr = upper(replace(?1,' ',''))"
   10.86 +    " );";
   10.87  
   10.88  static const char *sql_own_identities_retrieve =  
   10.89      "select address, fpr, username, "
   10.90 @@ -209,6 +255,7 @@
   10.91      int int_result;
   10.92      
   10.93      bool in_first = false;
   10.94 +    bool very_first = false;
   10.95  
   10.96      assert(sqlite3_threadsafe());
   10.97      if (!sqlite3_threadsafe())
   10.98 @@ -234,6 +281,10 @@
   10.99  
  10.100      _session->version = PEP_ENGINE_VERSION;
  10.101  
  10.102 +#ifdef DEBUG_ERRORSTACK
  10.103 +    _session->errorstack = new_stringlist("init()");
  10.104 +#endif
  10.105 +
  10.106      assert(LOCAL_DB);
  10.107      if (LOCAL_DB == NULL) {
  10.108          status = PEP_INIT_CANNOT_OPEN_DB;
  10.109 @@ -395,6 +446,21 @@
  10.110              &version,
  10.111              NULL
  10.112          );
  10.113 +
  10.114 +        assert(int_result == SQLITE_OK);
  10.115 +        
  10.116 +        void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
  10.117 +        
  10.118 +        int_result = sqlite3_create_function_v2(
  10.119 +            _session->db,
  10.120 +            "lower",
  10.121 +            1,
  10.122 +            SQLITE_UTF8 | SQLITE_DETERMINISTIC,
  10.123 +            NULL,
  10.124 +            xFunc_lower,
  10.125 +            NULL,
  10.126 +            NULL,
  10.127 +            NULL);
  10.128          assert(int_result == SQLITE_OK);
  10.129  
  10.130          if(version != 0) { 
  10.131 @@ -462,6 +528,11 @@
  10.132                  assert(int_result == SQLITE_OK);
  10.133              }
  10.134          }
  10.135 +        else { 
  10.136 +            // Version from DB was 0, it means this is initial setup.
  10.137 +            // DB has just been created, and all tables are empty.
  10.138 +            very_first = true;
  10.139 +        }
  10.140  
  10.141          if (version < atoi(_DDL_USER_VERSION)) {
  10.142              int_result = sqlite3_exec(
  10.143 @@ -475,7 +546,6 @@
  10.144              );
  10.145              assert(int_result == SQLITE_OK);
  10.146          }
  10.147 -
  10.148      }
  10.149  
  10.150      int_result = sqlite3_prepare_v2(_session->db, sql_log,
  10.151 @@ -490,6 +560,11 @@
  10.152              (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  10.153      assert(int_result == SQLITE_OK);
  10.154  
  10.155 +    int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  10.156 +            (int)strlen(sql_replace_identities_fpr), 
  10.157 +            &_session->replace_identities_fpr, NULL);
  10.158 +    assert(int_result == SQLITE_OK);
  10.159 +
  10.160      int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  10.161              (int)strlen(sql_set_person), &_session->set_person, NULL);
  10.162      assert(int_result == SQLITE_OK);
  10.163 @@ -525,6 +600,10 @@
  10.164              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  10.165      assert(int_result == SQLITE_OK);
  10.166  
  10.167 +    int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  10.168 +            (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  10.169 +    assert(int_result == SQLITE_OK);
  10.170 +
  10.171      int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  10.172              (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  10.173      assert(int_result == SQLITE_OK);
  10.174 @@ -635,11 +714,44 @@
  10.175      // runtime config
  10.176  
  10.177  #ifdef ANDROID
  10.178 -    _session->use_only_own_private_keys = true;
  10.179  #elif TARGET_OS_IPHONE
  10.180 -    _session->use_only_own_private_keys = true;
  10.181 -#else
  10.182 -    _session->use_only_own_private_keys = false;
  10.183 +#else /* Desktop */
  10.184 +    if (very_first)
  10.185 +    {
  10.186 +        // On first run, all private keys already present in PGP keyring 
  10.187 +        // are taken as own in order to seamlessly integrate with
  10.188 +        // pre-existing GPG setup.
  10.189 +
  10.190 +        ////////////////////////////// WARNING: ///////////////////////////
  10.191 +        // Considering all PGP priv keys as own is dangerous in case of 
  10.192 +        // re-initialization of pEp DB, while keeping PGP keyring as-is!
  10.193 +        //
  10.194 +        // Indeed, if pEpEngine did import spoofed private keys in previous
  10.195 +        // install, then those keys become automatically trusted in case 
  10.196 +        // pEp_management.db is deleted.
  10.197 +        //
  10.198 +        // A solution to distinguish bare GPG keyring from pEp keyring is
  10.199 +        // needed here. Then keys managed by pEpEngine wouldn't be
  10.200 +        // confused with GPG keys managed by the user through GPA.
  10.201 +        ///////////////////////////////////////////////////////////////////
  10.202 +        
  10.203 +        stringlist_t *keylist = NULL;
  10.204 +
  10.205 +        status = find_private_keys(_session, NULL, &keylist);
  10.206 +        assert(status != PEP_OUT_OF_MEMORY);
  10.207 +        if (status == PEP_OUT_OF_MEMORY)
  10.208 +            return PEP_OUT_OF_MEMORY;
  10.209 +        
  10.210 +        if (keylist != NULL && keylist->value != NULL)
  10.211 +        {
  10.212 +            stringlist_t *_keylist;
  10.213 +            for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
  10.214 +                status = set_own_key(_session, 
  10.215 +                                     "" /* address is unused in own_keys */,
  10.216 +                                     _keylist->value);
  10.217 +            }
  10.218 +        }
  10.219 +    }
  10.220  #endif
  10.221  
  10.222      // sync_session set to own session by default
  10.223 @@ -685,6 +797,8 @@
  10.224                  sqlite3_finalize(session->trustword);
  10.225              if (session->get_identity)
  10.226                  sqlite3_finalize(session->get_identity);
  10.227 +            if (session->replace_identities_fpr)
  10.228 +                sqlite3_finalize(session->replace_identities_fpr);        
  10.229              if (session->set_person)
  10.230                  sqlite3_finalize(session->set_person);
  10.231              if (session->set_device_group)
  10.232 @@ -701,6 +815,8 @@
  10.233                  sqlite3_finalize(session->unset_identity_flags);
  10.234              if (session->set_trust)
  10.235                  sqlite3_finalize(session->set_trust);
  10.236 +            if (session->update_trust_for_fpr)
  10.237 +                sqlite3_finalize(session->update_trust_for_fpr);
  10.238              if (session->get_trust)
  10.239                  sqlite3_finalize(session->get_trust);
  10.240              if (session->least_trust)
  10.241 @@ -749,6 +865,9 @@
  10.242          release_transport_system(session, out_last);
  10.243          release_cryptotech(session, out_last);
  10.244  
  10.245 +#ifdef DEBUG_ERRORSTACK
  10.246 +        free_stringlist(session->errorstack);
  10.247 +#endif
  10.248          free(session);
  10.249      }
  10.250  }
  10.251 @@ -765,19 +884,18 @@
  10.252      session->unencrypted_subject = enable;
  10.253  }
  10.254  
  10.255 -DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session,
  10.256 -        bool enable)
  10.257 -{
  10.258 -    assert(session);
  10.259 -    session->use_only_own_private_keys = enable;
  10.260 -}
  10.261 -
  10.262  DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  10.263  {
  10.264      assert(session);
  10.265      session->keep_sync_msg = enable;
  10.266  }
  10.267  
  10.268 +DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  10.269 +{
  10.270 +    assert(session);
  10.271 +    session->service_log = enable;
  10.272 +}
  10.273 +
  10.274  DYNAMIC_API PEP_STATUS log_event(
  10.275          PEP_SESSION session,
  10.276          const char *title,
  10.277 @@ -815,7 +933,25 @@
  10.278      } while (result == SQLITE_BUSY);
  10.279      sqlite3_reset(session->log);
  10.280  
  10.281 -    return status;
  10.282 +    return ADD_TO_LOG(status);
  10.283 +}
  10.284 +
  10.285 +DYNAMIC_API PEP_STATUS log_service(
  10.286 +        PEP_SESSION session,
  10.287 +        const char *title,
  10.288 +        const char *entity,
  10.289 +        const char *description,
  10.290 +        const char *comment
  10.291 +    )
  10.292 +{
  10.293 +    assert(session);
  10.294 +    if (!session)
  10.295 +        return PEP_ILLEGAL_VALUE;
  10.296 +
  10.297 +    if (session->service_log)
  10.298 +        return log_event(session, title, entity, description, comment);
  10.299 +    else
  10.300 +        return PEP_STATUS_OK;
  10.301  }
  10.302  
  10.303  DYNAMIC_API PEP_STATUS trustword(
  10.304 @@ -1105,13 +1241,15 @@
  10.305                  identity->user_id && identity->username))
  10.306          return PEP_ILLEGAL_VALUE;
  10.307  
  10.308 +    PEP_STATUS status = PEP_STATUS_OK;
  10.309 +    
  10.310      bool listed;
  10.311  
  10.312      bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
  10.313      
  10.314      if (has_fpr) {    
  10.315          // blacklist check
  10.316 -        PEP_STATUS status = blacklist_is_listed(session, identity->fpr, &listed);
  10.317 +        status = blacklist_is_listed(session, identity->fpr, &listed);
  10.318          assert(status == PEP_STATUS_OK);
  10.319          if (status != PEP_STATUS_OK)
  10.320              return status;
  10.321 @@ -1189,6 +1327,8 @@
  10.322              }
  10.323          }
  10.324  
  10.325 +        // status = set_trust(session, identity->user_id, identity->fpr,
  10.326 +        //                    identity->comm_type)
  10.327          sqlite3_reset(session->set_trust);
  10.328          sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
  10.329                  SQLITE_STATIC);
  10.330 @@ -1210,6 +1350,52 @@
  10.331          return PEP_COMMIT_FAILED;
  10.332  }
  10.333  
  10.334 +PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  10.335 +                                 const char* old_fpr, 
  10.336 +                                 const char* new_fpr) 
  10.337 +{
  10.338 +    assert(old_fpr);
  10.339 +    assert(new_fpr);
  10.340 +    
  10.341 +    if (!old_fpr || !new_fpr)
  10.342 +        return PEP_ILLEGAL_VALUE;
  10.343 +            
  10.344 +    sqlite3_reset(session->replace_identities_fpr);
  10.345 +    sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  10.346 +                      SQLITE_STATIC);
  10.347 +    sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  10.348 +                      SQLITE_STATIC);
  10.349 +
  10.350 +    int result = sqlite3_step(session->replace_identities_fpr);
  10.351 +    sqlite3_reset(session->replace_identities_fpr);
  10.352 +    
  10.353 +    if (result != SQLITE_DONE)
  10.354 +        return PEP_CANNOT_SET_IDENTITY;
  10.355 +
  10.356 +    return PEP_STATUS_OK;
  10.357 +}
  10.358 +
  10.359 +
  10.360 +PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  10.361 +                                const char* fpr, 
  10.362 +                                PEP_comm_type comm_type)
  10.363 +{
  10.364 +    if (!fpr)
  10.365 +        return PEP_ILLEGAL_VALUE;
  10.366 +        
  10.367 +    sqlite3_reset(session->update_trust_for_fpr);
  10.368 +    sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  10.369 +    sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  10.370 +            SQLITE_STATIC);
  10.371 +    int result = sqlite3_step(session->update_trust_for_fpr);
  10.372 +    sqlite3_reset(session->update_trust_for_fpr);
  10.373 +    if (result != SQLITE_DONE) {
  10.374 +        return PEP_CANNOT_SET_TRUST;
  10.375 +    }
  10.376 +    
  10.377 +    return PEP_STATUS_OK;
  10.378 +}
  10.379 +
  10.380  DYNAMIC_API PEP_STATUS set_device_group(
  10.381          PEP_SESSION session,
  10.382          const char *group_name
  10.383 @@ -1849,7 +2035,7 @@
  10.384      status = PEP_OUT_OF_MEMORY;
  10.385  
  10.386  the_end:
  10.387 -    return status;
  10.388 +    return ADD_TO_LOG(status);
  10.389  }
  10.390  
  10.391  DYNAMIC_API PEP_STATUS get_languagelist(
  10.392 @@ -2238,8 +2424,8 @@
  10.393  
  10.394  PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  10.395                               stringlist_t **keylist) {
  10.396 -    assert(session && pattern && keylist);
  10.397 -    if (!(session && pattern && keylist))
  10.398 +    assert(session && keylist);
  10.399 +    if (!(session && keylist))
  10.400          return PEP_ILLEGAL_VALUE;
  10.401      
  10.402      return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  10.403 @@ -2272,3 +2458,52 @@
  10.404  
  10.405      return PEP_STATUS_OK;
  10.406  }
  10.407 +
  10.408 +#ifdef DEBUG_ERRORSTACK
  10.409 +PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  10.410 +{
  10.411 +    char logline[48];
  10.412 +    if(status>0)
  10.413 +    {
  10.414 +        snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  10.415 +    }else{
  10.416 +        snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  10.417 +    }
  10.418 +    stringlist_add(session->errorstack, logline); // logline is copied! :-)
  10.419 +    return status;
  10.420 +}
  10.421 +
  10.422 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  10.423 +{
  10.424 +    return session->errorstack;
  10.425 +}
  10.426 +
  10.427 +DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  10.428 +{
  10.429 +    const int old_len = stringlist_length(session->errorstack);
  10.430 +    char buf[48];
  10.431 +    free_stringlist(session->errorstack);
  10.432 +    snprintf(buf, 47, "(%i elements cleared)", old_len);
  10.433 +    session->errorstack = new_stringlist(buf);
  10.434 +}
  10.435 +
  10.436 +#else
  10.437 +
  10.438 +static stringlist_t* dummy_errorstack = NULL;
  10.439 +
  10.440 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  10.441 +{
  10.442 +    if(dummy_errorstack == NULL)
  10.443 +    {
  10.444 +        dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  10.445 +    }
  10.446 +
  10.447 +    return dummy_errorstack;
  10.448 +}
  10.449 +
  10.450 +DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  10.451 +{
  10.452 +    // nothing to do here
  10.453 +}
  10.454 +
  10.455 +#endif
    11.1 --- a/src/pEpEngine.h	Mon May 08 15:48:46 2017 +0200
    11.2 +++ b/src/pEpEngine.h	Wed Jun 28 13:33:53 2017 +0200
    11.3 @@ -46,6 +46,7 @@
    11.4      PEP_KEY_HAS_AMBIG_NAME                          = 0x0202,
    11.5      PEP_GET_KEY_FAILED                              = 0x0203,
    11.6      PEP_CANNOT_EXPORT_KEY                           = 0x0204,
    11.7 +    PEP_CANNOT_EDIT_KEY                             = 0x0205,
    11.8      
    11.9      PEP_CANNOT_FIND_IDENTITY                        = 0x0301,
   11.10      PEP_CANNOT_SET_PERSON                           = 0x0381,
   11.11 @@ -67,6 +68,7 @@
   11.12  
   11.13      PEP_TRUSTWORD_NOT_FOUND                         = 0x0501,
   11.14      PEP_TRUSTWORDS_FPR_WRONG_LENGTH                 = 0x0502,
   11.15 +    PEP_TRUSTWORDS_DUPLICATE_FPR                    = 0x0503,
   11.16  
   11.17      PEP_CANNOT_CREATE_KEY                           = 0x0601,
   11.18      PEP_CANNOT_SEND_KEY                             = 0x0602,
   11.19 @@ -147,6 +149,25 @@
   11.20  DYNAMIC_API void release(PEP_SESSION session);
   11.21  
   11.22  
   11.23 +// const stringlist_t* get_errorstack(PEP_SESSION) - get the error stack for that session, if any
   11.24 +//
   11.25 +//  parameters:
   11.26 +//        session (in)    session handle
   11.27 +//
   11.28 +//    caveat:
   11.29 +//        To get a useful error stack you have to compile with -DDEBUG_ERRORSTACK
   11.30 +//        The error stack belongs to the session. Do no not change it!
   11.31 +DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session);
   11.32 +
   11.33 +
   11.34 +// void clear_errorstack(PEP_SESSION) - clear the error stack for that session, if any
   11.35 +//
   11.36 +//  parameters:
   11.37 +//        session (in)    session handle
   11.38 +//
   11.39 +DYNAMIC_API void clear_errorstack(PEP_SESSION session);
   11.40 +
   11.41 +
   11.42  // config_passive_mode() - enable passive mode
   11.43  //
   11.44  //  parameters:
   11.45 @@ -182,6 +203,14 @@
   11.46  DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable);
   11.47  
   11.48  
   11.49 +// config_service_log() - log more for service purposes
   11.50 +//
   11.51 +//      session (in)    session handle
   11.52 +//      enable (in)     flag if enabled or disabled
   11.53 +
   11.54 +DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable);
   11.55 +
   11.56 +
   11.57  // decrypt_and_verify() - decrypt and/or verify a message
   11.58  //
   11.59  //    parameters:
   11.60 @@ -296,6 +325,17 @@
   11.61      );
   11.62  
   11.63  
   11.64 +DYNAMIC_API PEP_STATUS log_service(PEP_SESSION session, const char *title,
   11.65 +        const char *entity, const char *description, const char *comment);
   11.66 +
   11.67 +#define _STR_(x) #x
   11.68 +#define _D_STR_(x) _STR_(x)
   11.69 +#define S_LINE _D_STR_(__LINE__)
   11.70 +
   11.71 +#define SERVICE_LOG(session, title, entity, desc) \
   11.72 +    log_service((session), (title), (entity), (desc), "service " __FILE__ ":" S_LINE)
   11.73 +
   11.74 +
   11.75  // trustword() - get the corresponding trustword for a 16 bit value
   11.76  //
   11.77  //    parameters:
   11.78 @@ -524,6 +564,11 @@
   11.79          pEp_identity **identity
   11.80      );
   11.81  
   11.82 +PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
   11.83 +                                 const char* old_fpr, 
   11.84 +                                 const char* new_fpr); 
   11.85 +
   11.86 +
   11.87  // set_identity() - set identity information
   11.88  //
   11.89  //    parameters:
   11.90 @@ -807,6 +852,14 @@
   11.91  
   11.92  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity);
   11.93  
   11.94 +PEP_STATUS set_trust(PEP_SESSION session, 
   11.95 +                            const char* user_id,
   11.96 +                            const char* fpr, 
   11.97 +                            PEP_comm_type comm_type);
   11.98 +                            
   11.99 +PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  11.100 +                                const char* fpr, 
  11.101 +                                PEP_comm_type comm_type);
  11.102  
  11.103  // least_trust() - get the least known trust level for a key in the database
  11.104  //
  11.105 @@ -905,6 +958,12 @@
  11.106          bool *revoked
  11.107      );
  11.108  
  11.109 +PEP_STATUS get_key_userids(
  11.110 +        PEP_SESSION session,
  11.111 +        const char* fpr,
  11.112 +        stringlist_t** keylist
  11.113 +    );
  11.114 +
  11.115  
  11.116  // get_crashdump_log() - get the last log messages out
  11.117  //
    12.1 --- a/src/pEp_internal.h	Mon May 08 15:48:46 2017 +0200
    12.2 +++ b/src/pEp_internal.h	Wed Jun 28 13:33:53 2017 +0200
    12.3 @@ -100,6 +100,7 @@
    12.4      sqlite3_stmt *log;
    12.5      sqlite3_stmt *trustword;
    12.6      sqlite3_stmt *get_identity;
    12.7 +    sqlite3_stmt *replace_identities_fpr;
    12.8      sqlite3_stmt *set_person;
    12.9      sqlite3_stmt *set_device_group;
   12.10      sqlite3_stmt *get_device_group;
   12.11 @@ -108,6 +109,7 @@
   12.12      sqlite3_stmt *set_identity_flags;
   12.13      sqlite3_stmt *unset_identity_flags;
   12.14      sqlite3_stmt *set_trust;
   12.15 +    sqlite3_stmt *update_trust_for_fpr;
   12.16      sqlite3_stmt *get_trust;
   12.17      sqlite3_stmt *least_trust;
   12.18      sqlite3_stmt *mark_compromized;
   12.19 @@ -159,11 +161,15 @@
   12.20  
   12.21      bool passive_mode;
   12.22      bool unencrypted_subject;
   12.23 -    bool use_only_own_private_keys;
   12.24      bool keep_sync_msg;
   12.25 +    bool service_log;
   12.26      
   12.27 +#ifdef DEBUG_ERRORSTACK
   12.28 +    stringlist_t* errorstack;
   12.29 +#endif
   12.30  };
   12.31  
   12.32 +
   12.33  PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
   12.34  void release_transport_system(PEP_SESSION session, bool out_last);
   12.35  
   12.36 @@ -178,14 +184,14 @@
   12.37  #else
   12.38  #ifdef ANDROID
   12.39  #include <android/log.h>
   12.40 -#define  LOG_MORE(...)  __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s ", __VA_ARGS__);
   12.41 +#define  LOG_MORE(...)  __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ", __VA_ARGS__);
   12.42  #else
   12.43  #include <stdio.h>
   12.44 -#define  LOG_MORE(...)  printf("pEpEngine DEBUG_LOG('%s','%s','%s')\n", __VA_ARGS__);
   12.45 +#define  LOG_MORE(...)  fprintf(stderr, "pEpEngine DEBUG_LOG('%s','%s','%s','%s')\n", __VA_ARGS__);
   12.46  #endif
   12.47  #define DEBUG_LOG(TITLE, ENTITY, DESC) {\
   12.48 -    log_event(session, (TITLE), (ENTITY), (DESC), "debug");\
   12.49 -    LOG_MORE((TITLE), (ENTITY), (DESC))\
   12.50 +    log_event(session, (TITLE), (ENTITY), (DESC), "debug " __FILE__ ":" S_LINE);\
   12.51 +    LOG_MORE((TITLE), (ENTITY), (DESC), __FILE__ ":" S_LINE)\
   12.52  }
   12.53  #endif
   12.54  
   12.55 @@ -306,3 +312,13 @@
   12.56  
   12.57      return comparison == 0;
   12.58  }
   12.59 +
   12.60 +
   12.61 +#ifdef DEBUG_ERRORSTACK
   12.62 +    PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status);
   12.63 +    #define ADD_TO_LOG(status)   session_add_error(session, __FILE__, __LINE__, (status))
   12.64 +    #define GOTO(label)          do{ (void)session_add_error(session, __FILE__, __LINE__, status); goto label; }while(0)
   12.65 +#else
   12.66 +    #define ADD_TO_LOG(status)   (status)
   12.67 +    #define GOTO(label)          goto label
   12.68 +#endif
    13.1 --- a/src/pgp_gpg.c	Mon May 08 15:48:46 2017 +0200
    13.2 +++ b/src/pgp_gpg.c	Wed Jun 28 13:33:53 2017 +0200
    13.3 @@ -39,8 +39,7 @@
    13.4          assert(length == stringlist_length(values));
    13.5          if (!(length == stringlist_length(values) &&
    13.6                length <= sizeof(unsigned int) * CHAR_BIT)) {
    13.7 -            r = Fclose(f);
    13.8 -            assert(r == 0);
    13.9 +            Fclose(f);
   13.10  
   13.11              return false;
   13.12          }
   13.13 @@ -62,6 +61,8 @@
   13.14  
   13.15                          if (i == n) {
   13.16                              r = Fclose(f);
   13.17 +                            if (r != 0)
   13.18 +                                return false;
   13.19                              return true;
   13.20                          }
   13.21                      }
   13.22 @@ -83,11 +84,15 @@
   13.23          if ((found & i) == 0) {
   13.24              r = Fprintf(f, "%s %s\n", _k->value, _v->value);
   13.25              assert(r >= 0);
   13.26 +            if(r<0)
   13.27 +                return false;
   13.28          }
   13.29      }
   13.30  
   13.31      r = Fclose(f);
   13.32      assert(r == 0);
   13.33 +    if (r != 0)
   13.34 +        return false;
   13.35  
   13.36      return true;
   13.37  }
   13.38 @@ -1352,6 +1357,8 @@
   13.39  
   13.40      reading = gpg.gpgme_data_read(dh, buffer, _size);
   13.41      assert(_size == reading);
   13.42 +    if(_size != reading)
   13.43 +        return PEP_CANNOT_EXPORT_KEY;
   13.44  
   13.45      // safeguard for the naive user
   13.46      buffer[_size] = 0;
   13.47 @@ -1547,7 +1554,6 @@
   13.48      gpgme_key_t key;
   13.49  
   13.50      assert(session);
   13.51 -    assert(pattern);
   13.52      assert(keylist);
   13.53  
   13.54      *keylist = NULL;
   13.55 @@ -1584,7 +1590,9 @@
   13.56                  gpgme_user_id_t kuid = key->uids;
   13.57                  // check that at least one uid's email matches pattern exactly
   13.58                  while(kuid) {
   13.59 -                    if(kuid->email && strcmp(kuid->email, pattern) == 0){
   13.60 +                    if((pattern && kuid->email && strcmp(kuid->email, pattern) == 0) ||
   13.61 +                       pattern == NULL /* match all */ )
   13.62 +                    { 
   13.63                          char *fpr = key->subkeys->fpr;
   13.64                          assert(fpr);
   13.65                          _k = stringlist_add(_k, fpr);
   13.66 @@ -1939,11 +1947,14 @@
   13.67      gpgme_error = gpg.gpgme_op_edit(session->ctx, key, renew_fsm, &handle,
   13.68              output);
   13.69      assert(gpgme_error == GPG_ERR_NO_ERROR);
   13.70 +    if(gpgme_error != GPG_ERR_NO_ERROR) {
   13.71 +        status = PEP_CANNOT_EDIT_KEY;
   13.72 +    }
   13.73  
   13.74      gpg.gpgme_data_release(output);
   13.75      gpg.gpgme_key_unref(key);
   13.76  
   13.77 -    return PEP_STATUS_OK;
   13.78 +    return status;
   13.79  }
   13.80  
   13.81  typedef struct _revoke_state {
   13.82 @@ -2126,11 +2137,14 @@
   13.83      gpgme_error = gpg.gpgme_op_edit(session->ctx, key, revoke_fsm, &handle,
   13.84              output);
   13.85      assert(gpgme_error == GPG_ERR_NO_ERROR);
   13.86 +    if(gpgme_error != GPG_ERR_NO_ERROR) {
   13.87 +        status = PEP_CANNOT_EDIT_KEY;
   13.88 +    }
   13.89  
   13.90      gpg.gpgme_data_release(output);
   13.91      gpg.gpgme_key_unref(key);
   13.92  
   13.93 -    return PEP_STATUS_OK;
   13.94 +    return status;
   13.95  }
   13.96  
   13.97  PEP_STATUS pgp_key_expired(
    14.1 --- a/src/pgp_netpgp.c	Mon May 08 15:48:46 2017 +0200
    14.2 +++ b/src/pgp_netpgp.c	Wed Jun 28 13:33:53 2017 +0200
    14.3 @@ -241,6 +241,9 @@
    14.4      unsigned i,j;
    14.5  
    14.6      *length = 0;
    14.7 +    
    14.8 +    if (str == NULL)
    14.9 +        return 0;
   14.10  
   14.11      while(*str && *length < PGP_FINGERPRINT_SIZE){
   14.12          while (*str == ' ') str++;
   14.13 @@ -1055,18 +1058,18 @@
   14.14      PEP_STATUS result;
   14.15      char *buffer;
   14.16      size_t buflen;
   14.17 +    const pgp_keyring_t *srcring;
   14.18  
   14.19      assert(session);
   14.20      assert(fprstr);
   14.21      assert(key_data);
   14.22      assert(size);
   14.23  
   14.24 -    // TODO : support export secret key
   14.25 -    // crashing stub until export secret supported
   14.26 -    assert(!secret);
   14.27      if (secret)
   14.28 -        return PEP_ILLEGAL_VALUE;
   14.29 -
   14.30 +        srcring = netpgp.secring;
   14.31 +    else
   14.32 +        srcring = netpgp.pubring;
   14.33 +    
   14.34      if (!session || !fprstr || !key_data || !size)
   14.35          return PEP_ILLEGAL_VALUE;
   14.36  
   14.37 @@ -1077,7 +1080,7 @@
   14.38      if (str_to_fpr(fprstr, fpr, &fprlen)) {
   14.39          unsigned from = 0;
   14.40  
   14.41 -        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp.io, netpgp.pubring,
   14.42 +        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp.io, srcring,
   14.43                                                  fpr, fprlen, &from,
   14.44                                                  NULL,0,0)) == NULL) {
   14.45              result = PEP_KEY_NOT_FOUND;
   14.46 @@ -1895,10 +1898,9 @@
   14.47      PEP_STATUS result;
   14.48  
   14.49      assert(session);
   14.50 -    assert(pattern);
   14.51      assert(keylist);
   14.52  
   14.53 -    if (!session || !pattern || !keylist )
   14.54 +    if (!session || !keylist )
   14.55      {
   14.56          return PEP_ILLEGAL_VALUE;
   14.57      }
    15.1 --- a/src/platform_windows.cpp	Mon May 08 15:48:46 2017 +0200
    15.2 +++ b/src/platform_windows.cpp	Wed Jun 28 13:33:53 2017 +0200
    15.3 @@ -139,9 +139,15 @@
    15.4      assert(filename);
    15.5  	assert(flag == RTLD_LAZY); // only lazy binding is implemented
    15.6  
    15.7 -    bool result = readRegistryString(HKEY_LOCAL_MACHINE,
    15.8 -            TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
    15.9 -            PATH_BUF_SIZE, NULL);
   15.10 +	// Look up GnuPG installation in current user scope
   15.11 +	bool result = readRegistryString(HKEY_CURRENT_USER,
   15.12 +		TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
   15.13 +		PATH_BUF_SIZE, NULL);
   15.14 +	// If not found in current user, look up in local machine
   15.15 +	if (!result)
   15.16 +		result = readRegistryString(HKEY_LOCAL_MACHINE,
   15.17 +			TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
   15.18 +			PATH_BUF_SIZE, NULL);
   15.19  	assert(result);
   15.20  	if (!result)
   15.21  		return NULL;
    16.1 --- a/src/sync.h	Mon May 08 15:48:46 2017 +0200
    16.2 +++ b/src/sync.h	Wed Jun 28 13:33:53 2017 +0200
    16.3 @@ -203,7 +203,7 @@
    16.4  
    16.5  #include "message.h"
    16.6  #include "sync_fsm.h"
    16.7 -
    16.8 +#include "sync_app.h"
    16.9  
   16.10  // this module is for being used WITHOUT the Transport API in transport.h
   16.11  // DO NOT USE IT WHEN USING Transport API!
   16.12 @@ -227,28 +227,6 @@
   16.13  
   16.14  typedef PEP_STATUS (*messageToSend_t)(void *obj, message *msg);
   16.15  
   16.16 -// TODO add this to generated code.
   16.17 -typedef enum _sync_handshake_signal {
   16.18 -    SYNC_NOTIFY_UNDEFINED = 0,
   16.19 -
   16.20 -    // request show handshake dialog
   16.21 -    SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
   16.22 -    SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
   16.23 -    SYNC_NOTIFY_INIT_FORM_GROUP,
   16.24 -    SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
   16.25 -
   16.26 -    // handshake process timed out
   16.27 -    SYNC_NOTIFY_TIMEOUT,
   16.28 -
   16.29 -    // handshake accepted by user
   16.30 -    SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
   16.31 -    SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
   16.32 -    SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
   16.33 -
   16.34 -    // handshake dialog must be closed
   16.35 -    SYNC_NOTIFY_OVERTAKEN
   16.36 -} sync_handshake_signal;
   16.37 -
   16.38  // notifyHandshake() - notify UI about sync handshaking process
   16.39  //
   16.40  //  parameters:
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/sync_app.h	Wed Jun 28 13:33:53 2017 +0200
    17.3 @@ -0,0 +1,34 @@
    17.4 +//
    17.5 +//  sync_app.h
    17.6 +//  pEpEngine
    17.7 +//
    17.8 +//  Created by Dirk Zimmermann on 16.05.17.
    17.9 +//  Copyright © 2017 Edouard Tisserant. All rights reserved.
   17.10 +//
   17.11 +
   17.12 +#ifndef sync_app_h
   17.13 +#define sync_app_h
   17.14 +
   17.15 +// TODO add this to generated code.
   17.16 +typedef enum _sync_handshake_signal {
   17.17 +    SYNC_NOTIFY_UNDEFINED = 0,
   17.18 +
   17.19 +    // request show handshake dialog
   17.20 +    SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
   17.21 +    SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
   17.22 +    SYNC_NOTIFY_INIT_FORM_GROUP,
   17.23 +    SYNC_NOTIFY_INIT_MOVE_OUR_DEVICE,
   17.24 +
   17.25 +    // handshake process timed out
   17.26 +    SYNC_NOTIFY_TIMEOUT,
   17.27 +
   17.28 +    // handshake accepted by user
   17.29 +    SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED,
   17.30 +    SYNC_NOTIFY_ACCEPTED_GROUP_CREATED,
   17.31 +    SYNC_NOTIFY_ACCEPTED_DEVICE_MOVED,
   17.32 +
   17.33 +    // handshake dialog must be closed
   17.34 +    SYNC_NOTIFY_OVERTAKEN
   17.35 +} sync_handshake_signal;
   17.36 +
   17.37 +#endif /* sync_app_h */
    18.1 --- a/src/sync_impl.c	Mon May 08 15:48:46 2017 +0200
    18.2 +++ b/src/sync_impl.c	Wed Jun 28 13:33:53 2017 +0200
    18.3 @@ -727,7 +727,7 @@
    18.4  }
    18.5  
    18.6  
    18.7 -#ifdef DEBUG_SYNC_XER_IN_MESSAGE_BODY
    18.8 +#ifndef NDEBUG
    18.9  static int _append(const void *buffer, size_t size, void *appkey)
   18.10  {
   18.11      char **dest_ptr = (char **)appkey;
   18.12 @@ -823,7 +823,7 @@
   18.13      free_identity(me);
   18.14      me = NULL;
   18.15  
   18.16 -#ifdef DEBUG_SYNC_XER_IN_MESSAGE_BODY
   18.17 +#ifndef NDEBUG
   18.18      asn_enc_rval_t er;
   18.19      er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg, 
   18.20                      XER_F_BASIC, _append, &_message->longmsg);
    19.1 --- a/test/Makefile	Mon May 08 15:48:46 2017 +0200
    19.2 +++ b/test/Makefile	Wed Jun 28 13:33:53 2017 +0200
    19.3 @@ -2,10 +2,10 @@
    19.4  # This file is under GNU General Public License 3.0
    19.5  # see LICENSE.txt
    19.6  
    19.7 +HERE := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
    19.8 +
    19.9  include ../Makefile.conf
   19.10  
   19.11 -export GNUPGHOME=.
   19.12 -
   19.13  CC?=g++ -std=gnu++11 -pthread
   19.14  CXX?=g++ -std=gnu++11 -pthread
   19.15  LD?=$(CXX)
   19.16 @@ -34,32 +34,50 @@
   19.17  # don't delete .o files!
   19.18  .PRECIOUS: %.o
   19.19  
   19.20 +unexport GNUPGHOME;
   19.21 +TEST_HOME=$(HERE)/test_home
   19.22 +TEST_HOME_SKEL=$(TEST_HOME)_skel
   19.23 +TEST_GNUPGHOME_SKEL=$(TEST_HOME)_skel/.gnupg
   19.24 +
   19.25 +ifeq ($(shell uname), Darwin)
   19.26 +    LIBPATH = DYLD_LIBRARY_PATH
   19.27 +    LLDB_BIN = /Applications/Xcode.app/Contents/Developer/usr/bin/lldb
   19.28 +else
   19.29 +    LIBPATH = LD_LIBRARY_PATH
   19.30 +    LLDB_BIN = lldb
   19.31 +endif
   19.32 +
   19.33 +TEST_CMD_PFX = $(LIBPATH)=$(HOME)/lib:../src HOME=$(TEST_HOME)
   19.34 +
   19.35 +test_home_skel:
   19.36 +	mkdir -p test_home_skel
   19.37 +	-cat 0x*.asc *_sec.asc | gpg2 --import --homedir $(TEST_GNUPGHOME_SKEL)
   19.38 +
   19.39 +test_home_: test_home_skel
   19.40 +	rm -rf test_home
   19.41 +	cp -a test_home_skel test_home
   19.42 +
   19.43  clean:
   19.44  	rm -f *.o $(TARGET) *.a *~ $(UNIT_TESTS) pep_Dokument_Titel.pdf msg4.asc
   19.45 -	rm -Rf *.dSYM .imported pubring.gpg secring.gpg random_seed *.conf trustdb.gpg
   19.46 +	rm -Rf *.dSYM test_home test_home_skel pubring.gpg secring.gpg random_seed *.conf trustdb.gpg
   19.47  
   19.48 -.imported:
   19.49 -	-cat 0x*.asc *_sec.asc | gpg2 --import
   19.50 -	touch .imported
   19.51 -
   19.52 -test: pEpEngineTest .imported
   19.53 -	LD_LIBRARY_PATH=~/lib:../src ./pEpEngineTest
   19.54 +test: pEpEngineTest test_home_
   19.55 +	$(TEST_CMD_PFX) ./pEpEngineTest
   19.56  
   19.57  %_test : %_test.o test_util.o
   19.58  	 $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
   19.59  
   19.60 -%_run : %
   19.61 -	LD_LIBRARY_PATH=~/lib:../src ./$<
   19.62 +%_run : % test_home_
   19.63 +	$(TEST_CMD_PFX) ./$<
   19.64  
   19.65 +%_lldb : % test_home_
   19.66 +	$(TEST_CMD_PFX) $(LLDB_BIN) ./$<
   19.67  
   19.68 -%_lldb : %
   19.69 -	LD_LIBRARY_PATH=~/lib:../src lldb ./$<
   19.70 +%_valgrind : % test_home_
   19.71 +	$(TEST_CMD_PFX) valgrind --leak-check=yes ./$<
   19.72  
   19.73 -%_valgrind : %
   19.74 -	LD_LIBRARY_PATH=~/lib:../src valgrind --leak-check=yes ./$<
   19.75 -
   19.76 -%_gdb : %
   19.77 -	LD_LIBRARY_PATH=~/lib:../src gdb ./$<
   19.78 +%_gdb : % test_home_
   19.79 +	$(TEST_CMD_PFX) gdb ./$<
   19.80  
   19.81  unit_tests: $(UNIT_TESTS) $(UNIT_TESTS_RUN)
   19.82  
    20.1 --- a/test/apple_mail_test.cc	Mon May 08 15:48:46 2017 +0200
    20.2 +++ b/test/apple_mail_test.cc	Wed Jun 28 13:33:53 2017 +0200
    20.3 @@ -26,16 +26,16 @@
    20.4  
    20.5      const string keytextkey1 = slurp("test_keys/pub/pep-test-apple-0x1CCBC7D7_pub.asc");
    20.6      const string keytextkey2 = slurp("test_keys/priv/pep-test-recip-0x08DB0AEE_priv.asc");
    20.7 +    const string keytextkey3 = slurp("test_keys/pub/pep-test-recip-0x08DB0AEE_pub.asc");
    20.8  
    20.9      PEP_STATUS statuskey1 = import_key(session, keytextkey1.c_str(), keytextkey1.length(), NULL);
   20.10      PEP_STATUS statuskey2 = import_key(session, keytextkey2.c_str(), keytextkey2.length(), NULL);
   20.11 +    PEP_STATUS statuskey3 = import_key(session, keytextkey3.c_str(), keytextkey3.length(), NULL);
   20.12          
   20.13      const string mailtext = slurp(mailfile);
   20.14 -    pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", NULL, PEP_OWN_USERID, "pEp Test Recipient");    
   20.15 +    pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", "93D19F24AD6F4C4BA9134AAF84D9217908DB0AEE", PEP_OWN_USERID, "pEp Test Recipient");    
   20.16      me->me = true;    
   20.17 -    PEP_STATUS status = update_identity(session, me);
   20.18 -    trust_personal_key(session, me);    
   20.19 -    status = update_identity(session, me);
   20.20 +    PEP_STATUS status = myself(session, me);
   20.21      
   20.22      pEp_identity * you = new_identity("pep.test.apple@pep-project.org", NULL, "TOFU_pep.test.apple@pep-project.org", "pEp Test Recipient");    
   20.23      you->me = false;    
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/case_and_dot_address_test.cc	Wed Jun 28 13:33:53 2017 +0200
    21.3 @@ -0,0 +1,80 @@
    21.4 +// This file is under GNU General Public License 3.0
    21.5 +// see LICENSE.txt
    21.6 +
    21.7 +#include <stdlib.h>
    21.8 +#include <string.h>
    21.9 +#include <time.h>
   21.10 +#include "platform.h"
   21.11 +#include <iostream>
   21.12 +#include <fstream>
   21.13 +#include <assert.h>
   21.14 +#include "mime.h"
   21.15 +#include "message_api.h"
   21.16 +#include "test_util.h"
   21.17 +
   21.18 +using namespace std;
   21.19 +
   21.20 +int main() {
   21.21 +    cout << "\n*** case_and_dot_address_test.cc ***\n\n";
   21.22 +
   21.23 +    PEP_SESSION session;
   21.24 +    
   21.25 +    cout << "calling init()\n";
   21.26 +    PEP_STATUS status = init(&session);   
   21.27 +    assert(status == PEP_STATUS_OK);
   21.28 +    assert(session);
   21.29 +    cout << "init() completed.\n";
   21.30 +    
   21.31 +    
   21.32 +    const string alice_pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   21.33 +    const string alice_priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
   21.34 +
   21.35 +    const char* alice_email_case = "pEp.teST.AlICe@pEP-pRoJeCt.ORG";
   21.36 +    const char* alice_email_dot = "pe.p.te.st.a.l.i.ce@pep-project.org";
   21.37 +    const char* alice_email_dotless = "peptestalice@pep-project.org";
   21.38 +    const char* alice_email_case_and_dot = "PE.p.teS.t.ALICE@pep-project.OrG";
   21.39 +
   21.40 +    PEP_STATUS statuspub = import_key(session, alice_pub_key.c_str(), alice_pub_key.length(), NULL);
   21.41 +    PEP_STATUS statuspriv = import_key(session, alice_priv_key.c_str(), alice_priv_key.length(), NULL);
   21.42 +    assert(statuspub == PEP_STATUS_OK);
   21.43 +    assert(statuspriv == PEP_STATUS_OK);
   21.44 +
   21.45 +    pEp_identity * alice_id = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
   21.46 +    status = update_identity(session, alice_id);
   21.47 +    assert(alice_id->fpr);
   21.48 +    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   21.49 +    free_identity(alice_id);
   21.50 +    alice_id = NULL;
   21.51 +
   21.52 +    alice_id = new_identity(alice_email_case, NULL, PEP_OWN_USERID, "Alice Test");
   21.53 +    status = update_identity(session, alice_id);
   21.54 +    assert(alice_id->fpr);
   21.55 +    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   21.56 +    free_identity(alice_id);
   21.57 +    alice_id = NULL;
   21.58 +
   21.59 +    alice_id = new_identity(alice_email_dot, NULL, PEP_OWN_USERID, "Alice Test");
   21.60 +    status = update_identity(session, alice_id);
   21.61 +    assert(alice_id->fpr);
   21.62 +    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   21.63 +    free_identity(alice_id);
   21.64 +    alice_id = NULL;
   21.65 +
   21.66 +    alice_id = new_identity(alice_email_dotless, NULL, PEP_OWN_USERID, "Alice Test");
   21.67 +    status = update_identity(session, alice_id);
   21.68 +    assert(alice_id->fpr);
   21.69 +    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   21.70 +    free_identity(alice_id);
   21.71 +    alice_id = NULL;
   21.72 +
   21.73 +    alice_id = new_identity(alice_email_case_and_dot, NULL, PEP_OWN_USERID, "Alice Test");
   21.74 +    status = update_identity(session, alice_id);
   21.75 +    assert(alice_id->fpr);
   21.76 +    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   21.77 +    free_identity(alice_id);
   21.78 +    alice_id = NULL;
   21.79 +    
   21.80 +    release(session);
   21.81 +
   21.82 +    return 0;
   21.83 +}
    22.1 --- a/test/encrypt_for_identity_test.cc	Mon May 08 15:48:46 2017 +0200
    22.2 +++ b/test/encrypt_for_identity_test.cc	Wed Jun 28 13:33:53 2017 +0200
    22.3 @@ -9,6 +9,7 @@
    22.4  #include <assert.h>
    22.5  #include "mime.h"
    22.6  #include "message_api.h"
    22.7 +#include "keymanagement.h"
    22.8  #include "test_util.h"
    22.9  
   22.10  using namespace std;
   22.11 @@ -35,9 +36,13 @@
   22.12      assert(statuspriv == PEP_STATUS_OK);
   22.13  
   22.14      cout << "creating message…\n";
   22.15 -    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
   22.16 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
   22.17      pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test");
   22.18      alice->me = true;
   22.19 +
   22.20 +    PEP_STATUS mystatus = myself(session, alice);
   22.21 +    assert(mystatus == PEP_STATUS_OK);
   22.22 +
   22.23      identity_list* to_list = new_identity_list(bob); // to bob
   22.24      message* outgoing_message = new_message(PEP_dir_outgoing);
   22.25      assert(outgoing_message);
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/test/external_revoke_test.cc	Wed Jun 28 13:33:53 2017 +0200
    23.3 @@ -0,0 +1,329 @@
    23.4 +// This file is under GNU General Public License 3.0
    23.5 +// see LICENSE.txt
    23.6 +
    23.7 +#include <stdlib.h>
    23.8 +#include <string.h>
    23.9 +#include <time.h>
   23.10 +#include "platform.h"
   23.11 +#include <iostream>
   23.12 +#include <fstream>
   23.13 +#include <assert.h>
   23.14 +#include "mime.h"
   23.15 +#include "message_api.h"
   23.16 +#include "test_util.h"
   23.17 +
   23.18 +using namespace std;
   23.19 +
   23.20 +int main() {
   23.21 +    cout << "\n*** external_revoke_test.cc ***\n\n";
   23.22 +
   23.23 +    PEP_SESSION session;
   23.24 +    
   23.25 +    cout << "calling init()\n";
   23.26 +    PEP_STATUS status = init(&session);   
   23.27 +    assert(status == PEP_STATUS_OK);
   23.28 +    assert(session);
   23.29 +    cout << "init() completed.\n";
   23.30 +
   23.31 +#ifndef NETPGP
   23.32 +    char* fprs[2];
   23.33 +
   23.34 +    const string fenris_pub_key = slurp("test_keys/pub/pep.test.fenris-0x4F3D2900_pub.asc");
   23.35 +    const string fenris_priv_key = slurp("test_keys/priv/pep.test.fenris-0x4F3D2900_priv.asc");
   23.36 +
   23.37 +    assert(fenris_pub_key.length() != 0);
   23.38 +    assert(fenris_priv_key.length() != 0);
   23.39 +    
   23.40 +    PEP_STATUS statuspub = import_key(session, fenris_pub_key.c_str(), fenris_pub_key.length(), NULL);
   23.41 +    PEP_STATUS statuspriv = import_key(session, fenris_priv_key.c_str(), fenris_priv_key.length(), NULL);
   23.42 +    assert(statuspub == PEP_STATUS_OK);
   23.43 +    assert(statuspriv == PEP_STATUS_OK);
   23.44 +
   23.45 +    // Create sender ID
   23.46 +    
   23.47 +    pEp_identity * me = new_identity("pep.test.fenris@thisstilldoesntwork.lu", "0969FA229DF21C832A64A04711B1B9804F3D2900", PEP_OWN_USERID, "Fenris Hawke");
   23.48 +    status = myself(session, me);
   23.49 +    
   23.50 +    // Create key
   23.51 +
   23.52 +    cout << "Creating new id for : ";
   23.53 +    char *uniqname = strdup("AAAAtestuser@testdomain.org");
   23.54 +    srandom(time(NULL));
   23.55 +    for(int i=0; i < 4;i++)
   23.56 +        uniqname[i] += random() & 0xf;
   23.57 +    
   23.58 +    cout << uniqname << "\n";
   23.59 +    pEp_identity * recip1 = new_identity(uniqname, NULL, NULL, "Test User");
   23.60 +
   23.61 +    status = generate_keypair(session, recip1);
   23.62 +    
   23.63 +    cout << "Generated fingerprint ";
   23.64 +    cout << recip1->fpr << "\n";
   23.65 +
   23.66 +    fprs[0] = strdup(recip1->fpr);
   23.67 +    
   23.68 +    cout << endl << "*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*" << endl;
   23.69 +    cout << "Trust and revoke single key, ensure trust changes, then generate new key and ensure rating is correct." << endl;
   23.70 +    cout << "*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*" << endl << endl;
   23.71 +    
   23.72 +    cout << endl << "---------------------------------------------------------" << endl;
   23.73 +    cout << "1a. Encrypt message for trusted partner." << endl;
   23.74 +    cout << "---------------------------------------------------------" << endl << endl;
   23.75 +
   23.76 +    cout << "Trusting personal key for " << uniqname << endl;
   23.77 +    // Trust it
   23.78 +    recip1->me = false;
   23.79 +    status = update_identity(session, recip1);
   23.80 +    status = trust_personal_key(session, recip1);
   23.81 +    status = update_identity(session, recip1);
   23.82 +    
   23.83 +    // TODO: Check trust?
   23.84 +    cout << "Done! Trusted personal key with fpr " << recip1->fpr << " for " << uniqname << endl;
   23.85 +
   23.86 +    const char* r1_userid = (recip1->user_id ? strdup(recip1->user_id) : NULL);
   23.87 +
   23.88 +    
   23.89 +    // encrypt something to the key
   23.90 +    cout << "Creating message…\n";
   23.91 +    identity_list* to_list = new_identity_list(identity_dup(recip1)); // to bob
   23.92 +    message* outgoing_msg = new_message(PEP_dir_outgoing);
   23.93 +    assert(outgoing_msg);
   23.94 +    outgoing_msg->from = identity_dup(me);
   23.95 +    outgoing_msg->to = to_list;
   23.96 +    outgoing_msg->shortmsg = strdup("Greetings, humans!");
   23.97 +    outgoing_msg->longmsg = strdup("This is a test of the emergency message system. This is only a test. BEEP.");
   23.98 +    outgoing_msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   23.99 +    cout << "Message created.\n";
  23.100 +
  23.101 +    message* encrypted_outgoing_msg = NULL;
  23.102 +
  23.103 +    cout << "Encrypting message to " << uniqname << "…\n";    
  23.104 +    status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
  23.105 +    cout << "Encrypted message with status " << tl_status_string(status) << endl;
  23.106 +    // check status
  23.107 +    assert(status == PEP_STATUS_OK);
  23.108 +    assert(encrypted_outgoing_msg);
  23.109 +
  23.110 +    cout << "Checking message recipient comm_type from message." << endl;
  23.111 +    // check comm_type
  23.112 +    cout << "comm_type: " << tl_ct_string(encrypted_outgoing_msg->to->ident->comm_type) << endl;
  23.113 +    assert(encrypted_outgoing_msg->to->ident->comm_type == PEP_ct_OpenPGP);
  23.114 +    
  23.115 +    status = get_trust(session, recip1);
  23.116 +    
  23.117 +    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  23.118 +    assert(recip1->comm_type == PEP_ct_OpenPGP); // FIXME: PEP_ct_pEp???
  23.119 +
  23.120 +    // decrypt message
  23.121 +    free_message(outgoing_msg);
  23.122 +    outgoing_msg = NULL;
  23.123 +
  23.124 +    stringlist_t* keylist = nullptr;
  23.125 +    PEP_rating rating;
  23.126 +    PEP_decrypt_flags_t flags;
  23.127 +
  23.128 +    cout << endl << "---------------------------------------------------------" << endl;
  23.129 +    cout << "1b. Decrypt message that was encrypted for trusted partner." << endl;
  23.130 +    cout << "---------------------------------------------------------" << endl << endl;
  23.131 +
  23.132 +    cout << "Decrypting message." << endl;
  23.133 +    status = decrypt_message(session, encrypted_outgoing_msg, &outgoing_msg, &keylist, &rating, &flags);
  23.134 +    cout << "Decrypted message with status " << tl_status_string(status) << endl;
  23.135 +    assert(status == PEP_STATUS_OK);
  23.136 +    assert(rating == PEP_rating_trusted);
  23.137 +
  23.138 +    // check rating
  23.139 +    cout << "Rating of decrypted message to trusted recip: " << tl_rating_string(rating) << endl;
  23.140 +    assert(rating == PEP_rating_trusted); // FIXME: trusted and anonymised?
  23.141 +    
  23.142 +    // check comm_type
  23.143 +    status = get_trust(session, recip1);
  23.144 +
  23.145 +    cout << "Recip's trust DB comm_type = " << tl_ct_string(recip1->comm_type) << endl;
  23.146 +    assert(recip1->comm_type == PEP_ct_OpenPGP); // FIXME: PEP_ct_pEp???
  23.147 +
  23.148 +    cout << endl << "---------------------------------------------------------" << endl;
  23.149 +    cout << "2a. Revoke key for (currently) trusted partner." << endl;
  23.150 +    cout << "---------------------------------------------------------" << endl << endl;
  23.151 +    // externally revoke key
  23.152 +    // (note - as of 23.5.17, revoke_key() doesn't touch the trust db, just the keyring, so we can do this)
  23.153 +
  23.154 +    cout << "Revoking key." << endl;
  23.155 +    status = get_identity(session, uniqname, r1_userid, &recip1);    
  23.156 +    status = revoke_key(session, recip1->fpr, "encrypt_for_identity_test");
  23.157 +    cout << "Status of revocation call for " << recip1->fpr << " is "<< tl_status_string(status) << endl;
  23.158 +
  23.159 +    // free messages
  23.160 +    free_message(outgoing_msg);
  23.161 +    free_message(encrypted_outgoing_msg);
  23.162 +    outgoing_msg = NULL;
  23.163 +    encrypted_outgoing_msg = NULL;
  23.164 +    
  23.165 +    // encrypt something to the key
  23.166 +    cout << "creating message…\n";
  23.167 +    to_list = new_identity_list(identity_dup(recip1)); // to bob
  23.168 +    outgoing_msg = new_message(PEP_dir_outgoing);
  23.169 +    assert(outgoing_msg);
  23.170 +    outgoing_msg->from = identity_dup(me);
  23.171 +    outgoing_msg->to = to_list;
  23.172 +    outgoing_msg->shortmsg = strdup("Greetings, humans!");
  23.173 +    outgoing_msg->longmsg = strdup("This is a test of the emergency message system. This is only a test. BEEP.");
  23.174 +    outgoing_msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
  23.175 +    cout << "message created.\n";
  23.176 +
  23.177 +    encrypted_outgoing_msg = NULL;
  23.178 +    message* decrypted_msg = NULL;
  23.179 +
  23.180 +    cout << endl << "---------------------------------------------------------" << endl;
  23.181 +    cout << "2b. Encrypt message for recip whose key has been externally revoked in the keyring, not the app." << endl;
  23.182 +    cout << "---------------------------------------------------------" << endl << endl;
  23.183 +
  23.184 +    status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
  23.185 +    cout << "Encryption returns with status " << tl_status_string(status) << endl;
  23.186 +
  23.187 +    PEP_comm_type ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
  23.188 +
  23.189 +    cout << endl << "---------------------------------------------------------" << endl;
  23.190 +    cout << "2c. Check trust of recip, whose only key has been revoked, once an encryption attempt has been made." << endl;
  23.191 +    cout << "---------------------------------------------------------" << endl << endl;
  23.192 +
  23.193 +    // check comm_type
  23.194 +    cout << "comm_type: " << tl_ct_string(ct) << endl;
  23.195 +    assert(ct == PEP_ct_key_revoked);
  23.196 +    
  23.197 +    status = get_trust(session, recip1);
  23.198 +
  23.199 +    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  23.200 +    assert(recip1->comm_type == PEP_ct_key_revoked);
  23.201 +
  23.202 +    cout << endl << "---------------------------------------------------------" << endl;
  23.203 +    cout << "2d. Try to decrypt message that was encrypted for revoked key guy." << endl;
  23.204 +    cout << "---------------------------------------------------------" << endl << endl;
  23.205 +    // decrypt message
  23.206 +//    free_message(outgoing_msg);
  23.207 +//    outgoing_msg = NULL;
  23.208 +    // FIXME: Make this make more sense
  23.209 +    status = decrypt_message(session, outgoing_msg, &decrypted_msg, &keylist, &rating, &flags);
  23.210 +    cout << "Decryption returns with status " << tl_status_string(status) << endl;
  23.211 +    assert(status == PEP_UNENCRYPTED);
  23.212 +    
  23.213 +    // check rating
  23.214 +    cout << "Rating of decrypted message to trusted recip: " << tl_rating_string(rating) << endl;
  23.215 +    assert(rating == PEP_rating_unencrypted);
  23.216 +
  23.217 +    ct = (decrypted_msg ? decrypted_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
  23.218 +
  23.219 +    cout << "comm_type: " << tl_ct_string(ct) << endl;
  23.220 +    assert(ct == PEP_ct_key_revoked);
  23.221 +    
  23.222 +    status = get_trust(session, recip1);
  23.223 +    
  23.224 +    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  23.225 +    assert(recip1->comm_type == PEP_ct_key_revoked);
  23.226 +
  23.227 +    free_message(encrypted_outgoing_msg);
  23.228 +    free_message(decrypted_msg);
  23.229 +    free_message(outgoing_msg);
  23.230 +    outgoing_msg = NULL;
  23.231 +    decrypted_msg = NULL;
  23.232 +    encrypted_outgoing_msg = NULL;
  23.233 +
  23.234 +    cout << endl << "---------------------------------------------------------" << endl;
  23.235 +    cout << "3a. Generate new key, but don't explicitly trust it." << endl;
  23.236 +    cout << "---------------------------------------------------------" << endl << endl;
  23.237 +
  23.238 +    // now: generate new key
  23.239 +    free(recip1->fpr);
  23.240 +    recip1->fpr = NULL;
  23.241 +    status = generate_keypair(session, recip1);
  23.242 +    
  23.243 +    cout << "Generated fingerprint \n";
  23.244 +    cout << recip1->fpr << "\n";
  23.245 +    fprs[1] = strdup(recip1->fpr);
  23.246 +
  23.247 +    // try again
  23.248 +    cout << endl << "---------------------------------------------------------" << endl;
  23.249 +    cout << "3b. Try to send something to the email address of our revoked friend, make sure a new key is used to encrypt." << endl;
  23.250 +    cout << "---------------------------------------------------------" << endl << endl;
  23.251 +    
  23.252 +    // encrypt something to the key
  23.253 +    cout << "Creating message…\n";
  23.254 +    to_list = new_identity_list(identity_dup(recip1)); // to bob
  23.255 +    outgoing_msg = new_message(PEP_dir_outgoing);
  23.256 +    assert(outgoing_msg);
  23.257 +    outgoing_msg->from = identity_dup(me);
  23.258 +    outgoing_msg->to = to_list;
  23.259 +    outgoing_msg->shortmsg = strdup("Greetings, humans!");
  23.260 +    outgoing_msg->longmsg = strdup("This is a test of the emergency message system. This is only a test. BEEP.");
  23.261 +    outgoing_msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
  23.262 +    cout << "Message created.\n";
  23.263 +
  23.264 +    status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
  23.265 +
  23.266 +    ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
  23.267 +
  23.268 +    // CHECK STATUS???
  23.269 +    cout << "Encryption returns with status " << tl_status_string(status) << endl;
  23.270 +
  23.271 +    // check comm_type
  23.272 +    cout << "comm_type: " << tl_ct_string(ct) << endl;
  23.273 +    assert(ct == PEP_ct_OpenPGP_unconfirmed);
  23.274 +    
  23.275 +    status = get_trust(session, recip1);
  23.276 +
  23.277 +    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  23.278 +    assert(recip1->comm_type == PEP_ct_OpenPGP_unconfirmed);
  23.279 +
  23.280 +    // decrypt message
  23.281 +//    free_message(outgoing_msg);
  23.282 +//    outgoing_msg = NULL;
  23.283 +
  23.284 +    cout << endl << "---------------------------------------------------------" << endl;
  23.285 +    cout << "3c. Decrypt... that... message!" << endl;
  23.286 +    cout << "---------------------------------------------------------" << endl << endl;
  23.287 +
  23.288 +
  23.289 +    status = decrypt_message(session, encrypted_outgoing_msg, &decrypted_msg, &keylist, &rating, &flags);
  23.290 +    cout << "Decryption returns with status " << tl_status_string(status) << endl;
  23.291 +    assert(status == PEP_STATUS_OK);
  23.292 +
  23.293 +    // check rating
  23.294 +    cout << "Rating of decrypted message to trusted recip: " << tl_rating_string(rating) << endl;
  23.295 +    assert(rating == PEP_rating_reliable);
  23.296 +
  23.297 +    ct = (decrypted_msg ? decrypted_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
  23.298 +
  23.299 +    cout << "comm_type: " << tl_ct_string(ct) << endl;
  23.300 +    assert(ct == PEP_ct_OpenPGP_unconfirmed);
  23.301 +    
  23.302 +    status = get_trust(session, recip1);
  23.303 +    
  23.304 +    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  23.305 +    assert(recip1->comm_type == PEP_ct_OpenPGP_unconfirmed);
  23.306 +
  23.307 +    free_message(encrypted_outgoing_msg);
  23.308 +    free_message(decrypted_msg);
  23.309 +    free_message(outgoing_msg);
  23.310 +    outgoing_msg = NULL;
  23.311 +    decrypted_msg = NULL;
  23.312 +    encrypted_outgoing_msg = NULL;
  23.313 +
  23.314 +    free_identity(me);
  23.315 +    free_identity(recip1);
  23.316 +    free(uniqname);
  23.317 +    
  23.318 +    delete_keypair(session, fprs[0]);    
  23.319 +    delete_keypair(session, fprs[1]);
  23.320 +    
  23.321 +    free(fprs[0]);
  23.322 +    free(fprs[1]);
  23.323 +    
  23.324 +#else
  23.325 +    cout << "Sorry, test is not defined for NETPGP at this time." << endl;
  23.326 +    
  23.327 +#endif
  23.328 +    
  23.329 +    release(session);
  23.330 +
  23.331 +    return 0;
  23.332 +}
    24.1 --- a/test/least_color_group_test.cc	Mon May 08 15:48:46 2017 +0200
    24.2 +++ b/test/least_color_group_test.cc	Wed Jun 28 13:33:53 2017 +0200
    24.3 @@ -43,7 +43,8 @@
    24.4      const string mailtext = slurp(mailfile);
    24.5      cout << "\t All files read successfully." << std::endl;
    24.6  
    24.7 -    pEp_identity * me1 = new_identity("pep.color.test.P@kgrothoff.org", NULL, 
    24.8 +    pEp_identity * me1 = new_identity("pep.color.test.P@kgrothoff.org", 
    24.9 +                                      "7EE6C60C68851954E1797F81EA59715E3EBE215C", 
   24.10                                        PEP_OWN_USERID, "Pep Color Test P (recip)");
   24.11      me1->me = true;
   24.12      PEP_STATUS status = update_identity(session, me1);
    25.1 --- a/test/least_common_denom_color_test.cc	Mon May 08 15:48:46 2017 +0200
    25.2 +++ b/test/least_common_denom_color_test.cc	Wed Jun 28 13:33:53 2017 +0200
    25.3 @@ -58,7 +58,6 @@
    25.4      
    25.5      message* msg_ptr = nullptr;
    25.6      message* dest_msg = nullptr;
    25.7 -    message* final_ptr = nullptr;
    25.8      stringlist_t* keylist = nullptr;
    25.9      PEP_rating rating;
   25.10      PEP_decrypt_flags_t flags;
   25.11 @@ -66,53 +65,69 @@
   25.12      status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   25.13      assert(status == PEP_STATUS_OK);
   25.14      assert(msg_ptr);
   25.15 -    final_ptr = msg_ptr;
   25.16 +
   25.17      status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   25.18 -    final_ptr = dest_msg ? dest_msg : msg_ptr;
   25.19 -  
   25.20 -    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
   25.21 -    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
   25.22 -    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
   25.23 -
   25.24 +    assert(status == PEP_STATUS_OK);
   25.25 +    assert(dest_msg);
   25.26      /* message is signed and no recip is mistrusted... */
   25.27      assert(color_from_rating(rating) == PEP_color_yellow);
   25.28  
   25.29 -    if (final_ptr == dest_msg)
   25.30 -    	free_message(dest_msg);
   25.31 -    free_message(msg_ptr);
   25.32 -    free_stringlist(keylist);
   25.33 +    cout << "shortmsg: " << dest_msg->shortmsg << endl << endl;
   25.34 +    cout << "longmsg: " << dest_msg->longmsg << endl << endl;
   25.35 +    cout << "longmsg_formatted: " << (dest_msg->longmsg_formatted ? dest_msg->longmsg_formatted : "(empty)") << endl << endl;
   25.36 +
   25.37 +    PEP_rating decrypt_rating = rating;
   25.38 +    
   25.39 +    /* re-evaluate rating, counting on optional fields */
   25.40 +    status = re_evaluate_message_rating(session, dest_msg, NULL, PEP_rating_undefined, &rating);
   25.41 +    assert(status == PEP_STATUS_OK);
   25.42 +    assert(color_from_rating(rating) == PEP_color_yellow);
   25.43 +
   25.44 +    /* re-evaluate rating, without optional fields */
   25.45 +    status = re_evaluate_message_rating(session, dest_msg, keylist, decrypt_rating, &rating);
   25.46 +    assert(status == PEP_STATUS_OK);
   25.47 +    assert(color_from_rating(rating) == PEP_color_yellow);
   25.48  
   25.49      /* Ok, now mistrust one recip */
   25.50      key_mistrusted(session, recip2);
   25.51 +
   25.52 +    /* re-evaluate rating, counting on optional fields */
   25.53 +    status = re_evaluate_message_rating(session, dest_msg, NULL, PEP_rating_undefined, &rating);
   25.54 +    assert(status == PEP_STATUS_OK);
   25.55 +    assert(color_from_rating(rating) == PEP_color_red);
   25.56 +
   25.57 +    /* re-evaluate rating, without optional fields */
   25.58 +    status = re_evaluate_message_rating(session, dest_msg, keylist, decrypt_rating, &rating);
   25.59 +    assert(status == PEP_STATUS_OK);
   25.60 +    assert(color_from_rating(rating) == PEP_color_red);
   25.61 +
   25.62 +    free_message(dest_msg);
   25.63 +    free_message(msg_ptr);
   25.64 +    free_stringlist(keylist);
   25.65      
   25.66      msg_ptr = nullptr;
   25.67      dest_msg = nullptr;
   25.68 -    final_ptr = nullptr;
   25.69      keylist = nullptr;
   25.70      rating = PEP_rating_unreliable;
   25.71  
   25.72      status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   25.73      assert(status == PEP_STATUS_OK);
   25.74      assert(msg_ptr);
   25.75 -    final_ptr = msg_ptr;
   25.76      status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   25.77 -    final_ptr = dest_msg ? dest_msg : msg_ptr;
   25.78    
   25.79 -    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
   25.80 -    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
   25.81 -    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
   25.82 +    cout << "shortmsg: " << dest_msg->shortmsg << endl << endl;
   25.83 +    cout << "longmsg: " << dest_msg->longmsg << endl << endl;
   25.84 +    cout << "longmsg_formatted: " << (dest_msg->longmsg_formatted ? dest_msg->longmsg_formatted : "(empty)") << endl << endl;
   25.85  
   25.86      /* message is signed and no recip is mistrusted... */
   25.87      assert(color_from_rating(rating) == PEP_color_red);
   25.88  
   25.89 -    if (final_ptr == dest_msg)
   25.90 -    	free_message(dest_msg);
   25.91 +    free_message(dest_msg);
   25.92      free_message(msg_ptr);
   25.93      free_stringlist(keylist);
   25.94  
   25.95      msg_ptr = nullptr;
   25.96      dest_msg = nullptr;
   25.97 -    final_ptr = nullptr;
   25.98      keylist = nullptr;
   25.99      rating = PEP_rating_unreliable;
  25.100      
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/test/pEp_subject_received_test.cc	Wed Jun 28 13:33:53 2017 +0200
    26.3 @@ -0,0 +1,222 @@
    26.4 +#include <iostream>
    26.5 +#include <iostream>
    26.6 +#include <fstream>
    26.7 +#include <string>
    26.8 +#include <cstring> // for strcmp()
    26.9 +#include <assert.h>
   26.10 +#include "blacklist.h"
   26.11 +#include "keymanagement.h"
   26.12 +#include "message_api.h"
   26.13 +#include "mime.h"
   26.14 +#include "test_util.h" // for slurp()
   26.15 +
   26.16 +using namespace std;
   26.17 +
   26.18 +int main(int argc, char** argv) {
   26.19 +
   26.20 +    cout << "\n*** check that pEp subject is handled properly in received mails ***\n\n";
   26.21 +
   26.22 +    PEP_SESSION session;
   26.23 +    
   26.24 +    cout << "calling init()\n";
   26.25 +    PEP_STATUS status1 = init(&session);   
   26.26 +    assert(status1 == PEP_STATUS_OK);
   26.27 +    assert(session);
   26.28 +    cout << "init() completed.\n";
   26.29 +
   26.30 +    const char* keytexts[3];
   26.31 +
   26.32 +    const string keytextkey1 = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   26.33 +    const string keytextkey2 = slurp("test_keys/priv/pep-test-recip-0x08DB0AEE_priv.asc");
   26.34 +    const string keytextkey3 = slurp("test_keys/pub/pep-test-recip-0x08DB0AEE_pub.asc");
   26.35 +    PEP_STATUS statuskey1 = import_key(session, keytextkey1.c_str(), keytextkey1.length(), NULL);
   26.36 +    PEP_STATUS statuskey2 = import_key(session, keytextkey2.c_str(), keytextkey2.length(), NULL);
   26.37 +    PEP_STATUS statuskey3 = import_key(session, keytextkey3.c_str(), keytextkey3.length(), NULL);
   26.38 +
   26.39 +    pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", "93D19F24AD6F4C4BA9134AAF84D9217908DB0AEE", PEP_OWN_USERID, "pEp Test Recipient");    
   26.40 +    me->me = true;    
   26.41 +    PEP_STATUS status = myself(session, me);
   26.42 +    
   26.43 +    pEp_identity * you = new_identity("pep.test.apple@pep-project.org", NULL, "TOFU_pep.test.apple@pep-project.org", "pEp Test Recipient");    
   26.44 +    you->me = false;    
   26.45 +    
   26.46 +    status = update_identity(session, you);
   26.47 +    trust_personal_key(session, you);
   26.48 +    status = update_identity(session, you);
   26.49 +
   26.50 +
   26.51 +    
   26.52 +    const char* mailfiles[] = {"test_mails/pEp_encrypted_subject_IS_pEp.eml",
   26.53 +                                "test_mails/pEp_subject_normal.eml",
   26.54 +                                "test_mails/pEp_subject_normal_signed.eml",
   26.55 +                                "test_mails/pEp_subject_normal_unencrypted.eml",
   26.56 +                                "test_mails/pEp_subject_pEp.eml",
   26.57 +                                "test_mails/pEp_unencrypted_pEp_subject.eml"};
   26.58 +                                
   26.59 +
   26.60 +    cout << "------------------------------------------------------------------------------------------" << endl;
   26.61 +    cout << "Test 1: Normal encrypted mail, pEp as substitute subject, regular subject in crypto text." << endl;
   26.62 +    cout << "------------------------------------------------------------------------------------------" << endl;
   26.63 +        
   26.64 +    string mailtext = slurp(mailfiles[1]);
   26.65 +    
   26.66 +    message* msg_ptr = nullptr;
   26.67 +    message* dest_msg = nullptr;
   26.68 +    message* final_ptr = nullptr;
   26.69 +    stringlist_t* keylist = nullptr;
   26.70 +    PEP_rating rating;
   26.71 +    PEP_decrypt_flags_t flags;
   26.72 +    
   26.73 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   26.74 +    assert(status == PEP_STATUS_OK);
   26.75 +    assert(msg_ptr);
   26.76 +    final_ptr = msg_ptr;
   26.77 +    status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   26.78 +    final_ptr = dest_msg ? dest_msg : msg_ptr;
   26.79 +  
   26.80 +    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
   26.81 +    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
   26.82 +    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
   26.83 +
   26.84 +    assert(strcmp("This is the usual pEp subject that should replace the above.", final_ptr->shortmsg) == 0);
   26.85 +
   26.86 +    cout << "Test 1: Subject replaced as expected." << endl << endl;
   26.87 +
   26.88 +    if (final_ptr == dest_msg)
   26.89 +    	free_message(dest_msg);
   26.90 +    free_message(msg_ptr);
   26.91 +    free_stringlist(keylist);
   26.92 +
   26.93 +    cout << "-------------------------------------------------------------------------------------------------" << endl;
   26.94 +    cout << "Test 2: Normal encrypted/signed mail, pEp as substitute subject, regular subject in crypto text." << endl;
   26.95 +    cout << "-------------------------------------------------------------------------------------------------" << endl;
   26.96 +
   26.97 +    msg_ptr = nullptr;
   26.98 +    dest_msg = nullptr;
   26.99 +    final_ptr = nullptr;
  26.100 +    keylist = nullptr;
  26.101 +    rating = PEP_rating_unreliable;
  26.102 +    
  26.103 +    mailtext = slurp(mailfiles[2]);
  26.104 +    
  26.105 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  26.106 +    assert(status == PEP_STATUS_OK);
  26.107 +    assert(msg_ptr);
  26.108 +    final_ptr = msg_ptr;
  26.109 +    status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
  26.110 +    final_ptr = dest_msg ? dest_msg : msg_ptr;
  26.111 +  
  26.112 +    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
  26.113 +    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
  26.114 +    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
  26.115 +
  26.116 +    assert(strcmp("Now signed!", final_ptr->shortmsg) == 0);
  26.117 +
  26.118 +    cout << "Test 2: Subject replaced as expected." << endl << endl;
  26.119 +
  26.120 +    if (final_ptr == dest_msg)
  26.121 +        free_message(dest_msg);
  26.122 +    free_message(msg_ptr);
  26.123 +    free_stringlist(keylist);
  26.124 +    
  26.125 +    cout << "-----------------------------------------------------------------------" << endl;
  26.126 +    cout << "Test 3: Encrypted mail, pEp as actual subject, no subject in body text." << endl;
  26.127 +    cout << "-----------------------------------------------------------------------" << endl;
  26.128 +
  26.129 +    msg_ptr = nullptr;
  26.130 +    dest_msg = nullptr;
  26.131 +    final_ptr = nullptr;
  26.132 +    keylist = nullptr;
  26.133 +    rating = PEP_rating_unreliable;
  26.134 +    
  26.135 +    mailtext = slurp(mailfiles[0]);
  26.136 +    
  26.137 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  26.138 +    assert(status == PEP_STATUS_OK);
  26.139 +    assert(msg_ptr);
  26.140 +    final_ptr = msg_ptr;
  26.141 +    status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
  26.142 +    final_ptr = dest_msg ? dest_msg : msg_ptr;
  26.143 +  
  26.144 +    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
  26.145 +    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
  26.146 +    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
  26.147 +
  26.148 +    assert(strcmp("pEp", final_ptr->shortmsg) == 0);
  26.149 +
  26.150 +    cout << "Test 3: Subject remains intact as desired." << endl << endl;
  26.151 +
  26.152 +    if (final_ptr == dest_msg)
  26.153 +        free_message(dest_msg);
  26.154 +    free_message(msg_ptr);
  26.155 +    free_stringlist(keylist);
  26.156 +
  26.157 +    cout << "-----------------------------------------------------------------------" << endl;
  26.158 +    cout << "Test 4: Encrypted mail, pEp as actual subject, pEp subject in body text." << endl;
  26.159 +    cout << "-----------------------------------------------------------------------" << endl;
  26.160 +
  26.161 +    msg_ptr = nullptr;
  26.162 +    dest_msg = nullptr;
  26.163 +    final_ptr = nullptr;
  26.164 +    keylist = nullptr;
  26.165 +    rating = PEP_rating_unreliable;
  26.166 +    
  26.167 +    mailtext = slurp(mailfiles[4]);
  26.168 +    
  26.169 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  26.170 +    assert(status == PEP_STATUS_OK);
  26.171 +    assert(msg_ptr);
  26.172 +    final_ptr = msg_ptr;
  26.173 +    status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
  26.174 +    final_ptr = dest_msg ? dest_msg : msg_ptr;
  26.175 +  
  26.176 +    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
  26.177 +    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
  26.178 +    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
  26.179 +
  26.180 +    assert(strcmp("pEp", final_ptr->shortmsg) == 0);
  26.181 +
  26.182 +    cout << "Test 4: Subject correct, in any event." << endl << endl;
  26.183 +
  26.184 +    if (final_ptr == dest_msg)
  26.185 +        free_message(dest_msg);
  26.186 +    free_message(msg_ptr);
  26.187 +    free_stringlist(keylist);
  26.188 +
  26.189 +    cout << "-------------------------------------------------------------------------" << endl;
  26.190 +    cout << "Test 5: Unencrypted variant where pEp in the subject line is the subject." << endl;
  26.191 +    cout << "-------------------------------------------------------------------------" << endl;
  26.192 +
  26.193 +    msg_ptr = nullptr;
  26.194 +    dest_msg = nullptr;
  26.195 +    final_ptr = nullptr;
  26.196 +    keylist = nullptr;
  26.197 +    rating = PEP_rating_unreliable;
  26.198 +    
  26.199 +    mailtext = slurp(mailfiles[5]);
  26.200 +    
  26.201 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  26.202 +    assert(status == PEP_STATUS_OK);
  26.203 +    assert(msg_ptr);
  26.204 +    final_ptr = msg_ptr;
  26.205 +    status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
  26.206 +    final_ptr = dest_msg ? dest_msg : msg_ptr;
  26.207 +  
  26.208 +    cout << "shortmsg: " << final_ptr->shortmsg << endl << endl;
  26.209 +    cout << "longmsg: " << final_ptr->longmsg << endl << endl;
  26.210 +    cout << "longmsg_formatted: " << (final_ptr->longmsg_formatted ? final_ptr->longmsg_formatted : "(empty)") << endl << endl;
  26.211 +
  26.212 +    assert(strcmp("pEp", final_ptr->shortmsg) == 0);
  26.213 +
  26.214 +    cout << "Test 5: Subject remains intact." << endl << endl;
  26.215 +
  26.216 +    if (final_ptr == dest_msg)
  26.217 +        free_message(dest_msg);
  26.218 +    free_message(msg_ptr);
  26.219 +    free_stringlist(keylist);
  26.220 +
  26.221 +        
  26.222 +    cout << "calling release()\n";
  26.223 +    release(session);
  26.224 +    return 0;
  26.225 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/test_keys/priv/pep.test.fenris-0x4F3D2900_priv.asc	Wed Jun 28 13:33:53 2017 +0200
    27.3 @@ -0,0 +1,57 @@
    27.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    27.5 +
    27.6 +lQOYBFk6bQsBCACgrAoz+IlRnJD5RA3HdevO/9rJVgTQJ/9BJX8zWmySXIqR53j1
    27.7 +A0zaPt2ZaiaEcCTVpTeDyTY0SSbLnaoin3Aru3wyiuKGT9HQAi21yhg3KZQp4Jnx
    27.8 +UPbBPVEkW79+vu0skVcYDLIBA7abec+VK4oRtG+1Kl1IUPuHv5Bh0TWwXna7h0RT
    27.9 +WsYZBvgapwc33Ux6Sbc3HV7JiFhccHnEC4jYLA8UyTt/aQzcz1XbtBVGUHpxuaDT
   27.10 +s8RYQd0zN86Y67pgfiGqITqSn3NlZevKOJHP6pZQxQqjwcIaKkeS/zehNwMgkWTz
   27.11 +SYIuER3zkCZjKkmwvDjO/irXQxoqWNY2ucQhABEBAAEAB/kBHe5h5Jsob6nGqygG
   27.12 +XYXoCzlyjLAdYKh4A+JMZtdE4DL6vIIdKpVKRMVxF367jR+wbYTYhsRN8j6Rtp+e
   27.13 +vH7WNagxc2uLiqVXKGtiwrbO4VwykKlj9vpe0bCNS7xQeFQj6xcQ0iZwS93lMEsB
   27.14 +YDYGP/vGewwpdciogwF7sJg1M5FrErvSTzbIfvD2+Q9+VJTHTDp5T7PBe0jzMNhs
   27.15 +gmLGbdWwdsK3lRITf3SHwnwNwhL19285IehQTO20nS/+Dbp52Nj4kV3tqq3rHgb7
   27.16 +ODA7sEREo1hVUX0FdPACIuWSKOi4atN6oj1c63deKGvIogh1ll27fM9SrE12BGRv
   27.17 +MxaxBADAjQTeA93xP2g2eNMk6uMrtZ8kHeNlgYXlh5iw3udjg8d8EsJPNHR9h3GM
   27.18 +1gcXP13n8BJOQ0pJYhfFpZdAMColsxJIUwemLMU41Pujo8QoObqTrpPjje6N13BC
   27.19 +Xdvs7oMfpkdaH14pSAmAhA/S1OcuBdoX9f0+uHSJuGeHS0RtaQQA1Z3S9BOfnkXl
   27.20 +rHfPaFUVOeNtaDrjrolnNeyC9unWTQx/2rf5zbWyxfz8vr12B318rkxsitvSosmj
   27.21 +Co7znQYn+TfYfq9deufIMxeuK+pr6qme321C6n5lHJjpDbw9EgGdzpjXPECS/NeE
   27.22 +Dvd2noqSeUysSRthNdWv6UhNfWngcfkD/2l2+iZyphNKhkIty6AzZI3y9FNEnJ4x
   27.23 +Kn3SQ+KKSQlS8BhffJhCbF0sNZ7ydZheuA3l8cwE9YJuCJsXZtda7V4myyBHbUky
   27.24 +ZijB0yw0dUnOjXXhDFvcHhC9XhNeKLGaBYSy1xEKrxFHpvjeeGsDvj8ZjEIXlRbo
   27.25 +PE0jMNa3aFwgPkS0WkZlbnJpcyBIYXdrZSAoVGVzdCBrZXkgZm9yIGV4dGVybmFs
   27.26 +IHJldm9rZSB0ZXN0cykgPHBlcC50ZXN0LmZlbnJpc0B0aGlzc3RpbGxkb2VzbnR3
   27.27 +b3JrLmx1PokBOQQTAQgAIwUCWTptCwIbAwcLCQgHAwIBBhUIAgkKCwQWAgMBAh4B
   27.28 +AheAAAoJEBGxuYBPPSkAYxcH/0u2pwPSQ4J6LR449DaUI40gG6rTSn2xSL3bMfD8
   27.29 +P12rFx56vC1CFZUimA+Va5mTF7SuoEtAAnsiUcu9X7slq3YVm6w+lOeUAvHoWaTZ
   27.30 +F/cuKZTLiZ5qAfwtEbMqzaSLAuWqaCNwC0iROb7gXHGz6Fsqzi4HsQwOHGhn0zaL
   27.31 +a6uN0ExLbYvyc7+nVD64hvHCVNwwYMHTKHJ838RhnsBfLz5j2sVjIDWLwdljJK6s
   27.32 +yQDqkQz+FkY/5HOizE/MP4CTRTvKD5dNYVZU9OFun/IW3zJKCUPZHg6UhsL4JBd+
   27.33 +6UuC9t/icYA4qyd/XQ8qy89G2cu8JcDV3SYVgj3JUKnEOXSdA5gEWTptCwEIAMfv
   27.34 +xubJv0wf8spgvutX8VKL2WDKU/A62ILvTR2pzRe+8nnHkImNxuC7AGtMWaIZkupK
   27.35 +t+LFb1ovLaaqIPG/ibfscusAk+QJrIvxbD0x2u9ImFbfYMyPRrn7b9iP6u5bk7j0
   27.36 +ntvOAMzAdaLvgt5kDsf8CaWc2WwTZbmTD9qaimsLTf6rpnSD6D7G6uAEkayfhBIe
   27.37 +TC56LwAfnsK+eqxQYfOmL29pXM43rzB/SsCIvrwT/phhtxg8Jc9OLzNCTbsNiJNt
   27.38 +185G7fEZlo91GnhZwAk0wWfgpINbYo4/c28xShM74psCF1eix1eyEl76CzfKJg0D
   27.39 +GYfFy25TOKn76ofKcr0AEQEAAQAH/01rlmAw2DAgoPHn85YLOEnIGJVH06gPCV7u
   27.40 +TjTB10auLJOmiNwS9+N21is2ZfEEqSSraThZToyj/y/t6hLiofAEEd3ZG+tuKZAJ
   27.41 +HOo3X3lP6ZmeJwwfIPqMmBtKY2UINhQlOUyRITMoBYVh7JG0OhsLiCrGqVSV0ErD
   27.42 +XRy/wgC/sSw6t9wDtNIpMfwfnhzue7RwSBV2659jPeP6fBPPc8J0D1dm8JuBzIE7
   27.43 +5El88dIjrnd8YQWFnVmV747itdzfm3xGFUVZSlbWPKR1+7Z09wV0Y/thdDBYHdOO
   27.44 +epT6IGqxdinyDKlxV4UcSD0VjhwvocNBlnJnsEkI+5XB24lbeQsEAOAuKvZ327J6
   27.45 +fA86hUzFrt7YZQzeyXNIbEVsPdyGImUb1s1o/X43CiFwG6o7ogIt08XU+toVV5y+
   27.46 +ilCfRq0wfZW/vZ9JawvtY/EyMUBgLcyeKgoXYH8YKCOw4t+tRO5Zol+mWQIOIcR6
   27.47 +KCSw6TiUmwzjGyIKapOAjiIbroaYy55LBADkULAZP97fK6KsvuMEzKprLolZzdjH
   27.48 +zKyaQUJPiGxYC/CiS0bpxz8lgVEoAggUB7TauCAWjrTfV+aIx3UmnZ+OO9pfJoId
   27.49 +pDa7rR90LyzCEe2ftODugi6O4N561htK0y2dfgWv2wnvx6z9W4fKM6MWP95WBXfM
   27.50 +y6AcSxf/lZFuFwQAwmAZBfoDXklAQycg1jNNwCQzxSeXHfUlspjLXZAho3CMUqd9
   27.51 +Td8vCqyrI4xdSp7Ko7CpfK8vfBWkWQBjWLw4d5JCAUapoH5dNPPfyfFOJe93P7Dk
   27.52 +9i4jmsK9VOb1ROcW347TGMaSDe41cODZ/S8FixZepvOhEXcQIPSiMTM9l9oxyIkB
   27.53 +HwQYAQgACQUCWTptCwIbDAAKCRARsbmATz0pAD2VB/9g/0VAkD6IpQSoQWYtFq0t
   27.54 +plbVm1kM5gS0O2caomyKRV6kRVGIJKCFvh2tmwuHu7cWklcdcAywPt1PtzYFqi9g
   27.55 +PkSBwz++O9CArQph8ifTgoWdxyo6mn7hanBnE9GMK8UYIDk9JnXWyPGFOjYv0ce3
   27.56 +yNEGtk4OexGypKBuF4OkFEbo/Xd2TW2OVKqKSGbT6tNP16VhNDk3Gkuj0DjTsVqP
   27.57 +VR1SYEbM6ME4oEuo0yhnHDVAs4nnx8aHU+ehoj1awJY9N9vJVRweBlyoq3CwvrCH
   27.58 +3SvAmqWLainevUklVnCvga9Xo0vRe9La7ARSOkVDxmDjIt/P4ETvbEElFHdFSs6c
   27.59 +=Hjdj
   27.60 +-----END PGP PRIVATE KEY BLOCK-----
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/test/test_keys/pub/pep.test.fenris-0x4F3D2900_pub.asc	Wed Jun 28 13:33:53 2017 +0200
    28.3 @@ -0,0 +1,30 @@
    28.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    28.5 +
    28.6 +mQENBFk6bQsBCACgrAoz+IlRnJD5RA3HdevO/9rJVgTQJ/9BJX8zWmySXIqR53j1
    28.7 +A0zaPt2ZaiaEcCTVpTeDyTY0SSbLnaoin3Aru3wyiuKGT9HQAi21yhg3KZQp4Jnx
    28.8 +UPbBPVEkW79+vu0skVcYDLIBA7abec+VK4oRtG+1Kl1IUPuHv5Bh0TWwXna7h0RT
    28.9 +WsYZBvgapwc33Ux6Sbc3HV7JiFhccHnEC4jYLA8UyTt/aQzcz1XbtBVGUHpxuaDT
   28.10 +s8RYQd0zN86Y67pgfiGqITqSn3NlZevKOJHP6pZQxQqjwcIaKkeS/zehNwMgkWTz
   28.11 +SYIuER3zkCZjKkmwvDjO/irXQxoqWNY2ucQhABEBAAG0WkZlbnJpcyBIYXdrZSAo
   28.12 +VGVzdCBrZXkgZm9yIGV4dGVybmFsIHJldm9rZSB0ZXN0cykgPHBlcC50ZXN0LmZl
   28.13 +bnJpc0B0aGlzc3RpbGxkb2VzbnR3b3JrLmx1PokBOQQTAQgAIwUCWTptCwIbAwcL
   28.14 +CQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEBGxuYBPPSkAYxcH/0u2pwPSQ4J6
   28.15 +LR449DaUI40gG6rTSn2xSL3bMfD8P12rFx56vC1CFZUimA+Va5mTF7SuoEtAAnsi
   28.16 +Ucu9X7slq3YVm6w+lOeUAvHoWaTZF/cuKZTLiZ5qAfwtEbMqzaSLAuWqaCNwC0iR
   28.17 +Ob7gXHGz6Fsqzi4HsQwOHGhn0zaLa6uN0ExLbYvyc7+nVD64hvHCVNwwYMHTKHJ8
   28.18 +38RhnsBfLz5j2sVjIDWLwdljJK6syQDqkQz+FkY/5HOizE/MP4CTRTvKD5dNYVZU
   28.19 +9OFun/IW3zJKCUPZHg6UhsL4JBd+6UuC9t/icYA4qyd/XQ8qy89G2cu8JcDV3SYV
   28.20 +gj3JUKnEOXS5AQ0EWTptCwEIAMfvxubJv0wf8spgvutX8VKL2WDKU/A62ILvTR2p
   28.21 +zRe+8nnHkImNxuC7AGtMWaIZkupKt+LFb1ovLaaqIPG/ibfscusAk+QJrIvxbD0x
   28.22 +2u9ImFbfYMyPRrn7b9iP6u5bk7j0ntvOAMzAdaLvgt5kDsf8CaWc2WwTZbmTD9qa
   28.23 +imsLTf6rpnSD6D7G6uAEkayfhBIeTC56LwAfnsK+eqxQYfOmL29pXM43rzB/SsCI
   28.24 +vrwT/phhtxg8Jc9OLzNCTbsNiJNt185G7fEZlo91GnhZwAk0wWfgpINbYo4/c28x
   28.25 +ShM74psCF1eix1eyEl76CzfKJg0DGYfFy25TOKn76ofKcr0AEQEAAYkBHwQYAQgA
   28.26 +CQUCWTptCwIbDAAKCRARsbmATz0pAD2VB/9g/0VAkD6IpQSoQWYtFq0tplbVm1kM
   28.27 +5gS0O2caomyKRV6kRVGIJKCFvh2tmwuHu7cWklcdcAywPt1PtzYFqi9gPkSBwz++
   28.28 +O9CArQph8ifTgoWdxyo6mn7hanBnE9GMK8UYIDk9JnXWyPGFOjYv0ce3yNEGtk4O
   28.29 +exGypKBuF4OkFEbo/Xd2TW2OVKqKSGbT6tNP16VhNDk3Gkuj0DjTsVqPVR1SYEbM
   28.30 +6ME4oEuo0yhnHDVAs4nnx8aHU+ehoj1awJY9N9vJVRweBlyoq3CwvrCH3SvAmqWL
   28.31 +ainevUklVnCvga9Xo0vRe9La7ARSOkVDxmDjIt/P4ETvbEElFHdFSs6c
   28.32 +=umG7
   28.33 +-----END PGP PUBLIC KEY BLOCK-----
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/test_mails/pEp_encrypted_subject_IS_pEp.eml	Wed Jun 28 13:33:53 2017 +0200
    29.3 @@ -0,0 +1,121 @@
    29.4 +Return-Path: <pep.test.alice@pep-project.org>
    29.5 +X-Original-To: krista@gnunet.org
    29.6 +Delivered-To: krista@gnunet.org
    29.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    29.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id BE55A1C00BC
    29.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:51 +0200 (CEST)
   29.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   29.11 +	id 94D2F1C0394; Mon, 12 Jun 2017 15:27:52 +0200 (CEST)
   29.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   29.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 6D2E21C037A
   29.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:52 +0200 (CEST)
   29.15 +Received: from vmmaildmz1.informatik.tu-muenchen.de (vmmaildmz1.informatik.tu-muenchen.de [131.159.0.87])
   29.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 5876E1C0383
   29.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:52 +0200 (CEST)
   29.18 +Received: by vmmaildmz1.informatik.tu-muenchen.de (Postfix, from userid 109)
   29.19 +	id 56F1F1C2D9D; Mon, 12 Jun 2017 15:27:52 +0200 (CEST)
   29.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   29.21 +	vmmaildmz1.informatik.tu-muenchen.de
   29.22 +X-Spam-Level: 
   29.23 +X-Spam-Status: No, score=-3.4 required=7.0 tests=AWL,BAYES_00,
   29.24 +	ENCRYPTED_MESSAGE,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,
   29.25 +	TVD_RCVD_SPACE_BRACKET,UNPARSEABLE_RELAY autolearn=no autolearn_force=no
   29.26 +	version=3.4.0-tuminfo_1
   29.27 +Received: from vmmaildmz1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   29.28 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTP id DE3C31C2D9E
   29.29 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:50 +0200 (CEST)
   29.30 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.149])
   29.31 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   29.32 +	(No client certificate requested)
   29.33 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTPS id CDD481C2D9B
   29.34 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:50 +0200 (CEST)
   29.35 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   29.36 +Received: from mailin.rzone.de ([unix socket])
   29.37 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   29.38 +	Mon, 12 Jun 2017 15:27:46 +0200 (CEST)
   29.39 +Authentication-Results: strato.com 1;
   29.40 +	spf=none
   29.41 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   29.42 +	dkim=none;
   29.43 +	domainkeys=none;
   29.44 +	dkim-adsp=none
   29.45 +		header.from="pep.test.alice@pep-project.org"
   29.46 +X-Strato-MessageType: email
   29.47 +X-RZG-CLASS-ID: mi00
   29.48 +Received-SPF: none
   29.49 +	client-ip=131.159.0.8;
   29.50 +	helo="mail-out1.informatik.tu-muenchen.de";
   29.51 +	envelope-from="pep.test.alice@pep-project.org";
   29.52 +	receiver=smtpin.rzone.de;
   29.53 +	identity=mailfrom;
   29.54 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   29.55 +	by smtpin.rzone.de (RZmta 40.9 OK)
   29.56 +	with ESMTPS id w03564t5CDRkYmx
   29.57 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   29.58 +	(Client did not present a certificate)
   29.59 +	for <pep.test.recip@kgrothoff.org>;
   29.60 +	Mon, 12 Jun 2017 15:27:46 +0200 (CEST)
   29.61 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   29.62 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id A8EC11013AE47
   29.63 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:27:40 +0200 (CEST)
   29.64 +To: pep.test.recip@kgrothoff.org
   29.65 +Reply-To: krista@pep-project.org
   29.66 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   29.67 +Subject: pEp
   29.68 +Organization: pEp
   29.69 +Message-ID: <5d37b6c2-9e5e-7217-c80e-1359da8faa5c@pep-project.org>
   29.70 +Date: Mon, 12 Jun 2017 15:27:40 +0200
   29.71 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   29.72 + Thunderbird/45.8.0
   29.73 +MIME-Version: 1.0
   29.74 +Content-Type: multipart/encrypted;
   29.75 + protocol="application/pgp-encrypted";
   29.76 + boundary="7vTKNA25GePB6VqgrM1km3gCfpFonmKj3"
   29.77 +
   29.78 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   29.79 +--7vTKNA25GePB6VqgrM1km3gCfpFonmKj3
   29.80 +Content-Type: application/pgp-encrypted
   29.81 +Content-Description: PGP/MIME version identification
   29.82 +
   29.83 +Version: 1
   29.84 +
   29.85 +--7vTKNA25GePB6VqgrM1km3gCfpFonmKj3
   29.86 +Content-Type: application/octet-stream; name="encrypted.asc"
   29.87 +Content-Description: OpenPGP encrypted message
   29.88 +Content-Disposition: inline; filename="encrypted.asc"
   29.89 +
   29.90 +-----BEGIN PGP MESSAGE-----
   29.91 +
   29.92 +hQEMA4FHqvEumyRHAQf6AkV51E1/uffFSc++oIPAoNCJU71NseNgW3s3XIQ/7TIQ
   29.93 +pDi6a6ksNdN+cJyMhfM7HnO06LjrUDYtgYPkZBHcTDZMWivW/7+5g8z60V3biIpw
   29.94 +mdUqhb+mZb4A0akMk+Ix8paoR8D7y4jmeLHwj/vbQ1J/E64rob9XPDWrLOW63chR
   29.95 +pg+XAo3VbkDKCms8PSuKehzMoTpZUcEVP47TF1OxuKZE0k7yJQ354RlPGxsl/6zM
   29.96 +O1+cJ7XdclkZj9gdeJAWzqCx6kTmDy2DA4e80BwMXXJnQtFIp4B55gTHvfbmxBRL
   29.97 +V8KDHOlvY/YSFV9sikjyaXbiweuqgiycsLb+qRziG4UBDANaAgXZcwg/TQEIAMg9
   29.98 +CVCJiYqS+ke1Zw0VNbb4BccrSBWL5iiQsPPUFOBld8jCFCGFZVBiik7O/XzRGWQh
   29.99 +qsYb2BNb0267viJS+IhTvihFybvR/l/gkzRLRfznFxbsRKgYAI6ipPr4wdAxvRkE
  29.100 +k0LvL3ckRgKtc2UORvfmhKRXu8Hj8dkYD0Asewnx7+p+s685MpyJ3zhhyifPzqKw
  29.101 +VH/6D7g26t3DjjQkvTvkiIMEvxT3beQN6QspdRtoDhHqAH0JhrZjEZyenneXE/AB
  29.102 +2CrnIfEU6V7S1EWP4Ond647K/F89ZG9LfTBpfmYuTXMKM39hmQaNcIsr8dr+mBif
  29.103 +nO2xRkyTMHAtyEk1dQnS6QFdLynwNLfsOvecztOBNBE/j6gH3dqKgZMg2e7ojK/Z
  29.104 +rNohpLMfZqzN37sfopm8htzK0Wg/l0CcgR8S4cUln06UzUm89GF9pokHYTnXYNYb
  29.105 +S2BMMVQ7gTpGDBfBFHVCK8xtCSFJJmxoxIzC9Ojl4JYfqJycip1QdWCWhXJDo0m9
  29.106 +4S+57m1UHAeyfT8v4ggEffVg2fgHF5VF58S3FC3HCtASAqljtmYVlHQSK0hSY00U
  29.107 +t9y/McqDXYuXXtT5O056q2VoYkWjTpvbvuk/TI3IU2np9owZwgHJwiA8I+BMQitd
  29.108 +LWRmSmoRBBHNsaORuEUZYMugZzcTD81C2v5PNDvawB7mcSFqrtI6K30TnZ5iu8DI
  29.109 +qJ9BdP7Htphqk9nusLT7XTYve/6/NC6rmnnEpQhrdXdzPDsyGe0H/s24xU3wFKBY
  29.110 +JdKyfKSJUkXjmCrqJrkq0wAHCaZYK5hLiobhYLGfxxjPpx2UFk33lYXL5R659Gjh
  29.111 +oIgZW5NWOxNRE1GRd2js+WaZy2dwvxeqNGEdEHgi6UN6JRf588lSYjbz+8u2TW21
  29.112 +whH5x5VfDpIqimPdknQwM/w8N2fYEhI4bWv0rp+D0m27hZaVXjInShEQq6YsjAs5
  29.113 +aP19C7WT+VK+FuvOEQ3nxPl+/fGOF5EoceuscxjCxkVu8Ijq4+xdu7Hl6ycJUu40
  29.114 +wGTKOy/rGg0TZ232SyUE83VyxAPtU0fTLvbZAcQaT+YTHqk/c4hdzPW/Ho8L1aZ0
  29.115 +Ax9PpkUHmm7+JS3sbfxyLMQ9Zz2GcE+SCIEyGuFTqO/ESmJUXTNQjDRmLuleOhZt
  29.116 +VmOezek2BEcvWZd5/0w6pd6UBjzXdSdTJA38nBr8Ao217xDMZiLoxg6xZbsG12et
  29.117 +mqWG9m/5dQRECrcN0lRdQqFovSkw7/Az7jOIm0v4ey+i6wmEblg3M0vm7Ky19l7Z
  29.118 +lm0+nC5XwR56n4VPtyRbGgLkI8w//NChYZJJOVpyVpfP57pKPhvhLNcaOk2d5gNU
  29.119 +KDg2bKXilzkMflVqw5eYN2EKCMlLx+hW5U1oSJJlQKqKXQ0qglUfSEzPmBt9Y0g1
  29.120 +DN+blh+m
  29.121 +=UZkH
  29.122 +-----END PGP MESSAGE-----
  29.123 +
  29.124 +--7vTKNA25GePB6VqgrM1km3gCfpFonmKj3--
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/test_mails/pEp_subject_normal.eml	Wed Jun 28 13:33:53 2017 +0200
    30.3 @@ -0,0 +1,112 @@
    30.4 +Return-Path: <pep.test.alice@pep-project.org>
    30.5 +X-Original-To: krista@gnunet.org
    30.6 +Delivered-To: krista@gnunet.org
    30.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    30.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id 98B571C00BC
    30.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:25:44 +0200 (CEST)
   30.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   30.11 +	id 620431C0383; Mon, 12 Jun 2017 15:25:45 +0200 (CEST)
   30.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   30.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 3F4961C037C
   30.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:25:45 +0200 (CEST)
   30.15 +Received: from vmmaildmz1.informatik.tu-muenchen.de (vmmaildmz1.informatik.tu-muenchen.de [131.159.0.87])
   30.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 2BCE31C037A
   30.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:25:45 +0200 (CEST)
   30.18 +Received: by vmmaildmz1.informatik.tu-muenchen.de (Postfix, from userid 109)
   30.19 +	id 2A4741C2D9D; Mon, 12 Jun 2017 15:25:45 +0200 (CEST)
   30.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   30.21 +	vmmaildmz1.informatik.tu-muenchen.de
   30.22 +X-Spam-Level: 
   30.23 +X-Spam-Status: No, score=-3.6 required=7.0 tests=BAYES_00,ENCRYPTED_MESSAGE,
   30.24 +	RCVD_IN_DNSWL_LOW,TVD_RCVD_SPACE_BRACKET,UNPARSEABLE_RELAY autolearn=no
   30.25 +	autolearn_force=no version=3.4.0-tuminfo_1
   30.26 +Received: from vmmaildmz1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   30.27 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTP id 6EF791C2D9E
   30.28 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:25:43 +0200 (CEST)
   30.29 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.144])
   30.30 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   30.31 +	(No client certificate requested)
   30.32 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTPS id 5E75D1C2D9B
   30.33 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:25:43 +0200 (CEST)
   30.34 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   30.35 +Received: from mailin.rzone.de ([unix socket])
   30.36 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   30.37 +	Mon, 12 Jun 2017 15:25:24 +0200 (CEST)
   30.38 +Authentication-Results: strato.com 1;
   30.39 +	spf=none
   30.40 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   30.41 +	dkim=none;
   30.42 +	domainkeys=none;
   30.43 +	dkim-adsp=none
   30.44 +		header.from="pep.test.alice@pep-project.org"
   30.45 +X-Strato-MessageType: email
   30.46 +X-RZG-CLASS-ID: mi00
   30.47 +Received-SPF: none
   30.48 +	client-ip=131.159.0.8;
   30.49 +	helo="mail-out1.informatik.tu-muenchen.de";
   30.50 +	envelope-from="pep.test.alice@pep-project.org";
   30.51 +	receiver=smtpin.rzone.de;
   30.52 +	identity=mailfrom;
   30.53 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   30.54 +	by smtpin.rzone.de (RZmta 40.9 OK)
   30.55 +	with ESMTPS id v06d9ft5CDPHXhF
   30.56 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   30.57 +	(Client did not present a certificate)
   30.58 +	for <pep.test.recip@kgrothoff.org>;
   30.59 +	Mon, 12 Jun 2017 15:25:17 +0200 (CEST)
   30.60 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   30.61 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id 4697F1013AE47
   30.62 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:25:11 +0200 (CEST)
   30.63 +Reply-To: krista@pep-project.org
   30.64 +To: pep.test.recip@kgrothoff.org
   30.65 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   30.66 +Subject: pEp
   30.67 +Organization: pEp
   30.68 +Message-ID: <92ee4ca2-17cd-bcf1-377c-3367470bb571@pep-project.org>
   30.69 +Date: Mon, 12 Jun 2017 15:25:10 +0200
   30.70 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   30.71 + Thunderbird/45.8.0
   30.72 +MIME-Version: 1.0
   30.73 +Content-Type: multipart/encrypted;
   30.74 + protocol="application/pgp-encrypted";
   30.75 + boundary="e7R73MXx31oWAX8HMqNvMDNt9cAMWtSTV"
   30.76 +
   30.77 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   30.78 +--e7R73MXx31oWAX8HMqNvMDNt9cAMWtSTV
   30.79 +Content-Type: application/pgp-encrypted
   30.80 +Content-Description: PGP/MIME version identification
   30.81 +
   30.82 +Version: 1
   30.83 +
   30.84 +--e7R73MXx31oWAX8HMqNvMDNt9cAMWtSTV
   30.85 +Content-Type: application/octet-stream; name="encrypted.asc"
   30.86 +Content-Description: OpenPGP encrypted message
   30.87 +Content-Disposition: inline; filename="encrypted.asc"
   30.88 +
   30.89 +-----BEGIN PGP MESSAGE-----
   30.90 +
   30.91 +hQEMA4FHqvEumyRHAQf+KW54G6f25yDJs6MdhWSs/766uFEIy8pq+j49AykOBsh2
   30.92 +W8BeB7yBqwjVFsBYPwGFNza187QHQVQlOHGRtxkXSX/iSym/O82YPvSwZj7GkKS9
   30.93 +sMgX2/dOMaEoTitn72f26ww5PvAqltJLD5TGhSM0RxK+0OemSrI0wDZxUb2Ll8DT
   30.94 +aVwpuKnLYFMcnk8SQLa3eZ/YpFV3TCMDFUgtIEqmHoh74dwemQjpP+qhbExZvY/k
   30.95 +rSZuJoU8siuLJ72vbEn8n2x8UCCfyTpacBZkC6Ukhsm/XrSg2GjqqzjSeR0T0Nbr
   30.96 +y/sFblbE8fbmouAf5k670oUot+j5aoHV79Rntcdm1oUBDANaAgXZcwg/TQEH/jhF
   30.97 +1ayYCROI8xEhj01Qbn60OtG+iKO+3B5/+uwizYgyW5mhKjrdgA/wsKMTMXj1BG+J
   30.98 +JJJ1TdEbxbL2UCai6nuHd0CbqJWSuTAicteKudUclAJHnpm2Qv+Yq2t/8JwJllMR
   30.99 +Wum8Cj4WuD0K3te5uHDZuu7Vfj9r3+7WYJ7FUkSYp2DUIFMM+hG+8OJtdjKd6kAA
  30.100 +FtAOijws+1r4jYFGYkCMRfnQatiFXf0n6Nr8qjSskkMtNQk41AG4LauYFTphR/G+
  30.101 +ayXPd8buDyBh3XuyoMcg5vLMJfWVTfiKM/wxv1jBBrQwFd5JpqCNr9dHYWMJ0gg9
  30.102 +aMdvaDEEd7I4VlwU+4DSwQMBF7R9V3cYj1XOxHjX2EikIxR/kviUrB8vDE4LAYJE
  30.103 +UFvoXgKRe4lQbQlLwoBp6R8L6mPTytLzlQnjQ4AJhPWhXkJUeCetURr5BzNCEfOy
  30.104 ++2Nq+9XLGM0wSCY09BOsGAQSL56kIGL61AnhvhpPUi9w9SOVjLHge6pzSzAW3h5E
  30.105 +vf8a8oGyLjyHR9VWBUqrMQ0tTWdHkoeHenXpwA+rckr0kzJXW1RJt2oQJEE0LI2I
  30.106 +0p9j7o6imaYWdtbHS7Kcbg2DxbT63QVOoO4OTPLHjYj0eqf1NDlwKBzQYaknNScI
  30.107 +LHnXrzMqqylU3ki8hUIh0K1ULernaA8LEIuegKMuguHCs2B/Xgee+Hor6l4XBRzD
  30.108 +V/8WFIU1lxthnYEceik/OD2U+LDKT4i+AogJAA+rCw0WbUC8f1HXQeV/8CVarcUn
  30.109 +GrS7AjjZlwQfiE8R/CtKdNaiJa4Z8GuQZJD/AqOe5zH0HLBykaheHS6ynw9yuNb7
  30.110 +d6lArIYdW5S8D0RDYRwu7z/lI3sgVgwiuoAk1OiYtrYUUNiXcpO59aE59iXjMW61
  30.111 +EvUAZzgfRyuzYdZtYNaM3FvUSm2aAsQRP+NJFW3YkqkbLvyo
  30.112 +=VpGy
  30.113 +-----END PGP MESSAGE-----
  30.114 +
  30.115 +--e7R73MXx31oWAX8HMqNvMDNt9cAMWtSTV--
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/test_mails/pEp_subject_normal_signed.eml	Wed Jun 28 13:33:53 2017 +0200
    31.3 @@ -0,0 +1,119 @@
    31.4 +Return-Path: <pep.test.alice@pep-project.org>
    31.5 +X-Original-To: krista@gnunet.org
    31.6 +Delivered-To: krista@gnunet.org
    31.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    31.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id 768301C00BC
    31.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:26:24 +0200 (CEST)
   31.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   31.11 +	id 4DD7D1C0383; Mon, 12 Jun 2017 15:26:25 +0200 (CEST)
   31.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   31.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 2AD621C037C
   31.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:26:25 +0200 (CEST)
   31.15 +Received: from vmmaildmz2.informatik.tu-muenchen.de (vmmaildmz2.informatik.tu-muenchen.de [131.159.0.88])
   31.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id 15DA11C037A
   31.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:26:25 +0200 (CEST)
   31.18 +Received: by vmmaildmz2.informatik.tu-muenchen.de (Postfix, from userid 109)
   31.19 +	id 13FCC1C2AE2; Mon, 12 Jun 2017 15:26:25 +0200 (CEST)
   31.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   31.21 +	vmmaildmz2.informatik.tu-muenchen.de
   31.22 +X-Spam-Level: 
   31.23 +X-Spam-Status: No, score=-2.6 required=7.0 tests=AWL,BAYES_00,
   31.24 +	ENCRYPTED_MESSAGE,RCVD_IN_DNSWL_LOW,TVD_RCVD_SPACE_BRACKET,UNPARSEABLE_RELAY
   31.25 +	autolearn=no autolearn_force=no version=3.4.0-tuminfo_1
   31.26 +Received: from vmmaildmz2.informatik.tu-muenchen.de (localhost [127.0.0.1])
   31.27 +	by vmmaildmz2.informatik.tu-muenchen.de (Postfix) with ESMTP id 953971C2AE1
   31.28 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:26:23 +0200 (CEST)
   31.29 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.144])
   31.30 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   31.31 +	(No client certificate requested)
   31.32 +	by vmmaildmz2.informatik.tu-muenchen.de (Postfix) with ESMTPS id 8540A1C2AE0
   31.33 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:26:23 +0200 (CEST)
   31.34 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   31.35 +Received: from mailin.rzone.de ([unix socket])
   31.36 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   31.37 +	Mon, 12 Jun 2017 15:26:02 +0200 (CEST)
   31.38 +Authentication-Results: strato.com 1;
   31.39 +	spf=none
   31.40 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   31.41 +	dkim=none;
   31.42 +	domainkeys=none;
   31.43 +	dkim-adsp=none
   31.44 +		header.from="pep.test.alice@pep-project.org"
   31.45 +X-Strato-MessageType: email
   31.46 +X-RZG-CLASS-ID: mi00
   31.47 +Received-SPF: none
   31.48 +	client-ip=131.159.0.8;
   31.49 +	helo="mail-out1.informatik.tu-muenchen.de";
   31.50 +	envelope-from="pep.test.alice@pep-project.org";
   31.51 +	receiver=smtpin.rzone.de;
   31.52 +	identity=mailfrom;
   31.53 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   31.54 +	by smtpin.rzone.de (RZmta 40.9 OK)
   31.55 +	with ESMTPS id v06d9ft5CDQ2Xj1
   31.56 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   31.57 +	(Client did not present a certificate)
   31.58 +	for <pep.test.recip@kgrothoff.org>;
   31.59 +	Mon, 12 Jun 2017 15:26:02 +0200 (CEST)
   31.60 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   31.61 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id BEAA21013AE47
   31.62 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:25:56 +0200 (CEST)
   31.63 +To: pep.test.recip@kgrothoff.org
   31.64 +Reply-To: krista@pep-project.org
   31.65 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   31.66 +Subject: pEp
   31.67 +Organization: pEp
   31.68 +Message-ID: <988e71f4-df80-906e-8bbb-68d48069d4ac@pep-project.org>
   31.69 +Date: Mon, 12 Jun 2017 15:25:56 +0200
   31.70 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   31.71 + Thunderbird/45.8.0
   31.72 +MIME-Version: 1.0
   31.73 +Content-Type: multipart/encrypted;
   31.74 + protocol="application/pgp-encrypted";
   31.75 + boundary="hcW81WNiFhQC1SNIcls8J07V1b1sXtfCA"
   31.76 +
   31.77 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   31.78 +--hcW81WNiFhQC1SNIcls8J07V1b1sXtfCA
   31.79 +Content-Type: application/pgp-encrypted
   31.80 +Content-Description: PGP/MIME version identification
   31.81 +
   31.82 +Version: 1
   31.83 +
   31.84 +--hcW81WNiFhQC1SNIcls8J07V1b1sXtfCA
   31.85 +Content-Type: application/octet-stream; name="encrypted.asc"
   31.86 +Content-Description: OpenPGP encrypted message
   31.87 +Content-Disposition: inline; filename="encrypted.asc"
   31.88 +
   31.89 +-----BEGIN PGP MESSAGE-----
   31.90 +
   31.91 +hQEMA4FHqvEumyRHAQf+OCG4FM0n6pVREVP2kAUzJWy6NAgRYs4cj7pr5hDoUqZY
   31.92 +lBIfVPqNM2rG2xaSpNLfe1iY5mySKL42M+s/QM0cvfnOlS6p3U58EamslElZ9UhD
   31.93 +hBUrX/1NJwdoKyR07Wq3A1UFFYQMYsszPwoC82SCFOhYjEmdZ8/nppViUk3aAUvq
   31.94 +do80ZzvNnlJqgwPEUmMEy9p19XJxQQwG75yHmUsoTvgi9ELvJpEzAjeYFABNzuNE
   31.95 +lh5whuMqmVbEafAYtopB+dwxQxSUdQUHntLU2MrbH8QXGtP98ZaDTHg/Zj24zkUG
   31.96 +Ur/5DZJgzDMrAttorpp/2/NMmakIezy7JaoGQtyYRYUBDANaAgXZcwg/TQEIALLR
   31.97 +7OlIlUYelrktOnrkTy8BrrEuUj95uBM5TkkvWIfR2b3ylC5iWwa/RlIU4RC0VH3j
   31.98 +epwLQNJJKFi/qKwxReE+RMKZW00loUuYnVWeaj58ExTNsdpFJDut35AIp8FNzTmy
   31.99 +C4xv5VVZZnolRd6CW0GUuxEe1zXq1MiyuGHu5AwFgWl728KaRXF2tEVyrQt/okXx
  31.100 +kF7yWkO4oo25VZWCrboUc1FND/7dbfP/PtLKIj05l+xwNaIEt1gb1IM7SxjN+2Tx
  31.101 +Ayp/w1npFhugBkSV3JaIk9dfHpMlLP5URZn30dXElK0an7aB8IwZWwdObo4zlevI
  31.102 +K4nN+UU1Z/kN1guxYDbS6QGOo2Y8829kaOXkBC3HDQEkef631jj1FuVB6VJvhb0u
  31.103 +5EKaxyw8aVxodRQaK9CcKCqwDlnyhHqd4fdMjPk9zTV9xrnqSdC5yKoAhBJ9sFef
  31.104 +Qv5qjYiBUhB+7uGMvRifvO+bT+8q44IS7z/bdXJFjbImgtx57yKvujyvrZlDe6q3
  31.105 +1nzS1jqMQ8NCDP/CKs5WUlaH9LIQ/NWF10EulTjaZ0QZ6iNU0MTqmhs4ZJIsPmBo
  31.106 +g6Qz9x8imV37cC9lHhw/vp99Dal9YulTxdYZnWSfTh289bHqaMEXGYJUsDh3IEYx
  31.107 +UP1bzza+N2dqeiysDmeTNhbZvwk54VmaKMrj/ut/3WIrsulBY7YxE/azle78Ydab
  31.108 +/tKu5YUbVydnVJ6y1s4yASjaOG7ycMIaXggWKUIfWh5Y7BLFHYbcMMltPrspftW7
  31.109 +tjtbL1SUHw0NTfCkBqRv4GpvIAXTCmlxvLw//ee1JZ0nuLnQZBF2GQ0wJVsbunT9
  31.110 +dUschdnIWLfWlueldt+5wOkB6L4quoZ7LWefMQu/b3bg/GWoBtuC3fJDnCsbJO07
  31.111 +nJxZTPxsI3iFUGGtXkg4jGC+yDMlQu3a7LwEkKzx9LT/S1OUndpaBQr6YjyrnET6
  31.112 +w1Hz6jLb5t/2fzrBwkKw1TCu4+pkevIGaGxgQY6TB15jcmWRkUF3sakTrH0UOCSq
  31.113 +wEzFoPF4+WjtXNk/wHw8zkrW7QCe+wbjLjwcUUK/ulKT9/II/k/aUwTt+GzWCGVq
  31.114 +KWq7VLtwa8lrJ74R+XISks9/Hv/nJ8Ay1DfpcQU2HQSnQpSrXupXIA+VoHU/b8xD
  31.115 +YcgqaRKsGYHUANjNs4PpplXlEHp5bpF/ZOpfVAJNnGQ96Cj182DLQgiB0j7Ishjv
  31.116 +XoNDVL45KKW0uWjimZbCauWrD6tjZfBmydymezbPLCB9R+tE68TA/XmpXzInXWML
  31.117 +YDK7tS8TYEkodzSkfDeB7BtXBRIxH4vm2M0E0OdJuLxjrOYeIH4xToUslS9pdog0
  31.118 +z3aqPQbXF4hFc8Fso83dmoc26mQd3H0LrP7yF4HR
  31.119 +=gLhG
  31.120 +-----END PGP MESSAGE-----
  31.121 +
  31.122 +--hcW81WNiFhQC1SNIcls8J07V1b1sXtfCA--
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/test_mails/pEp_subject_normal_unencrypted.eml	Wed Jun 28 13:33:53 2017 +0200
    32.3 @@ -0,0 +1,75 @@
    32.4 +Return-Path: <pep.test.alice@pep-project.org>
    32.5 +X-Original-To: krista@gnunet.org
    32.6 +Delivered-To: krista@gnunet.org
    32.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    32.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id 140C01C00BC
    32.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:21 +0200 (CEST)
   32.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   32.11 +	id DAE901C0390; Mon, 12 Jun 2017 15:27:21 +0200 (CEST)
   32.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   32.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id B86091C0383
   32.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:21 +0200 (CEST)
   32.15 +Received: from vmmaildmz1.informatik.tu-muenchen.de (vmmaildmz1.informatik.tu-muenchen.de [131.159.0.87])
   32.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id AE13F1C037A
   32.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:21 +0200 (CEST)
   32.18 +Received: by vmmaildmz1.informatik.tu-muenchen.de (Postfix, from userid 109)
   32.19 +	id AC51F1C2D9F; Mon, 12 Jun 2017 15:27:21 +0200 (CEST)
   32.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   32.21 +	vmmaildmz1.informatik.tu-muenchen.de
   32.22 +X-Spam-Level: 
   32.23 +X-Spam-Status: No, score=-3.1 required=7.0 tests=AWL,BAYES_00,
   32.24 +	RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,TVD_RCVD_SPACE_BRACKET,
   32.25 +	UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.0-tuminfo_1
   32.26 +Received: from vmmaildmz1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   32.27 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTP id 3B30C1C2D9E
   32.28 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:20 +0200 (CEST)
   32.29 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.148])
   32.30 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   32.31 +	(No client certificate requested)
   32.32 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTPS id 2AEF61C2D9B
   32.33 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:27:20 +0200 (CEST)
   32.34 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   32.35 +Received: from mailin.rzone.de ([unix socket])
   32.36 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   32.37 +	Mon, 12 Jun 2017 15:27:00 +0200 (CEST)
   32.38 +Authentication-Results: strato.com 1;
   32.39 +	spf=none
   32.40 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   32.41 +	dkim=none;
   32.42 +	domainkeys=none;
   32.43 +	dkim-adsp=none
   32.44 +		header.from="pep.test.alice@pep-project.org"
   32.45 +X-Strato-MessageType: email
   32.46 +X-RZG-CLASS-ID: mi00
   32.47 +Received-SPF: none
   32.48 +	client-ip=131.159.0.8;
   32.49 +	helo="mail-out1.informatik.tu-muenchen.de";
   32.50 +	envelope-from="pep.test.alice@pep-project.org";
   32.51 +	receiver=smtpin.rzone.de;
   32.52 +	identity=mailfrom;
   32.53 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   32.54 +	by smtpin.rzone.de (RZmta 40.9 OK)
   32.55 +	with ESMTPS id T01d0bt5CDR0XKI
   32.56 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   32.57 +	(Client did not present a certificate)
   32.58 +	for <pep.test.recip@kgrothoff.org>;
   32.59 +	Mon, 12 Jun 2017 15:27:00 +0200 (CEST)
   32.60 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   32.61 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id 1DF211013AE47
   32.62 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:26:55 +0200 (CEST)
   32.63 +Reply-To: krista@pep-project.org
   32.64 +To: pep.test.recip@kgrothoff.org
   32.65 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   32.66 +Subject: pEp
   32.67 +Organization: pEp
   32.68 +Message-ID: <6205efbe-684d-9f21-8a2e-887d46a145e6@pep-project.org>
   32.69 +Date: Mon, 12 Jun 2017 15:26:54 +0200
   32.70 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   32.71 + Thunderbird/45.8.0
   32.72 +MIME-Version: 1.0
   32.73 +Content-Type: text/plain; charset=utf-8
   32.74 +Content-Transfer-Encoding: 7bit
   32.75 +
   32.76 +Subject: Unencrypted try...
   32.77 +
   32.78 +La la la...
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/test/test_mails/pEp_subject_pEp.eml	Wed Jun 28 13:33:53 2017 +0200
    33.3 @@ -0,0 +1,120 @@
    33.4 +Return-Path: <pep.test.alice@pep-project.org>
    33.5 +X-Original-To: krista@gnunet.org
    33.6 +Delivered-To: krista@gnunet.org
    33.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    33.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id 1C8731C00BC
    33.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:28:42 +0200 (CEST)
   33.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   33.11 +	id E78B01C0383; Mon, 12 Jun 2017 15:28:42 +0200 (CEST)
   33.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   33.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id C414C1C037C
   33.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:28:42 +0200 (CEST)
   33.15 +Received: from vmmaildmz2.informatik.tu-muenchen.de (vmmaildmz2.informatik.tu-muenchen.de [131.159.0.88])
   33.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id AFA401C037A
   33.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:28:42 +0200 (CEST)
   33.18 +Received: by vmmaildmz2.informatik.tu-muenchen.de (Postfix, from userid 109)
   33.19 +	id AE03E1C2AE1; Mon, 12 Jun 2017 15:28:42 +0200 (CEST)
   33.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   33.21 +	vmmaildmz2.informatik.tu-muenchen.de
   33.22 +X-Spam-Level: 
   33.23 +X-Spam-Status: No, score=-2.9 required=7.0 tests=AWL,BAYES_00,
   33.24 +	ENCRYPTED_MESSAGE,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,
   33.25 +	TVD_RCVD_SPACE_BRACKET,UNPARSEABLE_RELAY autolearn=no autolearn_force=no
   33.26 +	version=3.4.0-tuminfo_1
   33.27 +Received: from vmmaildmz2.informatik.tu-muenchen.de (localhost [127.0.0.1])
   33.28 +	by vmmaildmz2.informatik.tu-muenchen.de (Postfix) with ESMTP id 441B11C2AE0
   33.29 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:28:41 +0200 (CEST)
   33.30 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.149])
   33.31 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   33.32 +	(No client certificate requested)
   33.33 +	by vmmaildmz2.informatik.tu-muenchen.de (Postfix) with ESMTPS id 3420F1C2ADF
   33.34 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:28:41 +0200 (CEST)
   33.35 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   33.36 +Received: from mailin.rzone.de ([unix socket])
   33.37 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   33.38 +	Mon, 12 Jun 2017 15:28:27 +0200 (CEST)
   33.39 +Authentication-Results: strato.com 1;
   33.40 +	spf=none
   33.41 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   33.42 +	dkim=none;
   33.43 +	domainkeys=none;
   33.44 +	dkim-adsp=none
   33.45 +		header.from="pep.test.alice@pep-project.org"
   33.46 +X-Strato-MessageType: email
   33.47 +X-RZG-CLASS-ID: mi00
   33.48 +Received-SPF: none
   33.49 +	client-ip=131.159.0.8;
   33.50 +	helo="mail-out1.informatik.tu-muenchen.de";
   33.51 +	envelope-from="pep.test.alice@pep-project.org";
   33.52 +	receiver=smtpin.rzone.de;
   33.53 +	identity=mailfrom;
   33.54 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   33.55 +	by smtpin.rzone.de (RZmta 40.9 OK)
   33.56 +	with ESMTPS id R04db2t5CDSRaBk
   33.57 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   33.58 +	(Client did not present a certificate)
   33.59 +	for <pep.test.recip@kgrothoff.org>;
   33.60 +	Mon, 12 Jun 2017 15:28:27 +0200 (CEST)
   33.61 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   33.62 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id E7A551013AE47
   33.63 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:28:20 +0200 (CEST)
   33.64 +Reply-To: krista@pep-project.org
   33.65 +To: pep.test.recip@kgrothoff.org
   33.66 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   33.67 +Subject: pEp
   33.68 +Organization: pEp
   33.69 +Message-ID: <1779982d-d48e-6d8c-2dcb-a2c337c496cb@pep-project.org>
   33.70 +Date: Mon, 12 Jun 2017 15:28:20 +0200
   33.71 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   33.72 + Thunderbird/45.8.0
   33.73 +MIME-Version: 1.0
   33.74 +Content-Type: multipart/encrypted;
   33.75 + protocol="application/pgp-encrypted";
   33.76 + boundary="xNhsqki3RTDSnTgiBbeAIkT3t5whv1bAM"
   33.77 +
   33.78 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   33.79 +--xNhsqki3RTDSnTgiBbeAIkT3t5whv1bAM
   33.80 +Content-Type: application/pgp-encrypted
   33.81 +Content-Description: PGP/MIME version identification
   33.82 +
   33.83 +Version: 1
   33.84 +
   33.85 +--xNhsqki3RTDSnTgiBbeAIkT3t5whv1bAM
   33.86 +Content-Type: application/octet-stream; name="encrypted.asc"
   33.87 +Content-Description: OpenPGP encrypted message
   33.88 +Content-Disposition: inline; filename="encrypted.asc"
   33.89 +
   33.90 +-----BEGIN PGP MESSAGE-----
   33.91 +
   33.92 +hQEMA4FHqvEumyRHAQgAjsyn0zCm0jHAp+SshDzqhMFNPuRc8VhDK9DpxiA1jLy8
   33.93 +bH2CKJIZEWApyfmwX5xLEXhfr0wb4BthHDXLzHCDqLSFo5FoavTwNL44kaX83yPv
   33.94 +Ts2WrvOcXGRpNLD94tvyDBqngtk3yKYaSkKKPok4Ou5gHrIDJaNZf/mybmPa0aTX
   33.95 +BEOxgAaRZJoPhgeVF8/twwiDv+ixFtdnPx9gGUXvgc5tPyrIkFkWtwrsoS2RmtJT
   33.96 +QqdsMmPbTFrsZ+d7qhdkcedeoKRg84SlXgtFpXkkbKHB/NU2ZQ2h2xTeUqdkFGN7
   33.97 +vBv17C+5jv8wzYlrlni9P1Mbc+dVBZTal9gYtBGwxIUBDANaAgXZcwg/TQEH/0vs
   33.98 +xQCJEdqbHKLz+xOmrpQEoFLdf2W9B7z2jGQe9F0K+gnPE3E+1wVf/IQgLj4YDXtN
   33.99 +Gkzc6J3UPBN9b1WSTPcJQ47hU5IXO/Sb39dU9X1s01JtCorTKmHlefosg6YaZ8CX
  33.100 +OhTkGYHqcJa9xE8kOMi4xnhP2Z3xaSkPSQvQ4WDWSapOwDkcM2a59Nwbu5PIGZpj
  33.101 +FM9WVLawN1/SVbaKOUEhFKdbl7UYW64JNWE6ZaLa0sfigt4QaXd5GrQcP2vmVVGz
  33.102 +WOuCaEb/HnxgiUvLQI2tCnW8aWluc6PnNk3HwLydvCL0tHSXPJno4Wbs1GzRJ4G7
  33.103 +CleoojpLytgTfIlZ7anS6QEAXXAuWGT3jddP4hcTnsfX40bQnIH1m49RX/4OHuMY
  33.104 +n7RyzSfyVghBQeA3fEQ48ep3WHuFHEn0Kn9rvcr/JZRO2NM4nBv1FjOIBTUMTlX+
  33.105 +hf0F/mYz1ycNg/rt6Taf9xcIP0IzRfQEa/dFqnEnBYCxGvRSr+EnMzg+ETT1p+aa
  33.106 +YAyjsbikhOqmle9G4LFUyblMmIlwFvAklAAlXTUJAEn3pc5mxH6vz0JitDpLdFDM
  33.107 +pW51y0HYgUNKS+9+qoVK2WXhkK/+hCbLzWVwzN5FlsIPucH+L+afquR6W5IKA8uZ
  33.108 +ixDPokbP1H608f/TobwX988nWby54kihoxaMvmEDbqT5Ivi5hHDhj5e79mxhUoZx
  33.109 +wb6fsm+d2vewDRhSIUF6/iioPaQt2AhmHNMBUYS5RrlOY8mc9BP8PwKym5SgkpE4
  33.110 +NKxoMjbQwUi3SHseA1hluMBieV+d7nYHqwBtSgMC/ax/AcDwmoLusXlf3OiBytdL
  33.111 +2v4OtPu6kt/QIlEABEDlqDK70wM6BChzWYrc5ErsixZ9NHunNshAjYsVeNtStOFV
  33.112 +TPGiy7a8rKB3xJhqzZhhLh9ly8JxVNfkb2LVXP/yzBS8LJpCluzyXZZpH2Q2a8lP
  33.113 +t71tjf/R/Uff2ZeF5yWO7zldyoEfx00yQWDyfmM6zHm17moXH5Mql2ZvTI0C0mk6
  33.114 +wDYNVEFe9YIXvxhdu5ym67ba8t5eV2t3c4zdhFy5YHZOC/KvpcZBLcvLY2jgVmNr
  33.115 +UYNqKpGK9m03jHRT2ZuG6F19QrxKqUIvgnYWsenecCvjjOIcWH7KqqNp+d4RyNRr
  33.116 +4VyoJk9nxzlUT/wKQJ6d5OtY5wytCCxpv8ihBFS3R2f0Sk2yXOgKE2sq0DEicWe+
  33.117 +x8Yqg3C/47hrtiUnEwwmp3VEYHfBTaaXMUkpmoRJ066u+8K2Jfo/pQnX6vcyUpvY
  33.118 +tJNqH+SMYKMXVBigU0ayWQFwVcoNEqFNVTm9K3MBQlIQiYqumBptG8rYhzF/eSUC
  33.119 +doDA15Ibgsk=
  33.120 +=P9h8
  33.121 +-----END PGP MESSAGE-----
  33.122 +
  33.123 +--xNhsqki3RTDSnTgiBbeAIkT3t5whv1bAM--
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/test/test_mails/pEp_unencrypted_pEp_subject.eml	Wed Jun 28 13:33:53 2017 +0200
    34.3 @@ -0,0 +1,73 @@
    34.4 +Return-Path: <pep.test.alice@pep-project.org>
    34.5 +X-Original-To: krista@gnunet.org
    34.6 +Delivered-To: krista@gnunet.org
    34.7 +Received: from vmmailrelay1.informatik.tu-muenchen.de (mailrelay1.informatik.tu-muenchen.de [131.159.254.14])
    34.8 +	by sam.net.in.tum.de (Postfix) with ESMTP id 39CD11C00BC
    34.9 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:36:35 +0200 (CEST)
   34.10 +Received: by vmmailrelay1.informatik.tu-muenchen.de (Postfix, from userid 109)
   34.11 +	id 0CEA81C0390; Mon, 12 Jun 2017 15:36:36 +0200 (CEST)
   34.12 +Received: from vmmailrelay1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   34.13 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id DE7711C0383
   34.14 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:36:35 +0200 (CEST)
   34.15 +Received: from vmmaildmz1.informatik.tu-muenchen.de (vmmaildmz1.informatik.tu-muenchen.de [131.159.0.87])
   34.16 +	by vmmailrelay1.informatik.tu-muenchen.de (Postfix) with ESMTP id D3D7A1C037A
   34.17 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:36:35 +0200 (CEST)
   34.18 +Received: by vmmaildmz1.informatik.tu-muenchen.de (Postfix, from userid 109)
   34.19 +	id D22771C2D9E; Mon, 12 Jun 2017 15:36:35 +0200 (CEST)
   34.20 +X-Spam-Checker-Version: SpamAssassin 3.4.0-tuminfo_1 (2014-02-07) on
   34.21 +	vmmaildmz1.informatik.tu-muenchen.de
   34.22 +X-Spam-Level: 
   34.23 +X-Spam-Status: No, score=-2.9 required=7.0 tests=AWL,BAYES_00,
   34.24 +	RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,TVD_RCVD_SPACE_BRACKET,
   34.25 +	UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.0-tuminfo_1
   34.26 +Received: from vmmaildmz1.informatik.tu-muenchen.de (localhost [127.0.0.1])
   34.27 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTP id 615241C2D9E
   34.28 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:36:34 +0200 (CEST)
   34.29 +Received: from mi4-p00-ob.smtp.rzone.de (mi4-p00-ob.smtp.rzone.de [81.169.146.146])
   34.30 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
   34.31 +	(No client certificate requested)
   34.32 +	by vmmaildmz1.informatik.tu-muenchen.de (Postfix) with ESMTPS id 50C3E1C2D9B
   34.33 +	for <krista@gnunet.org>; Mon, 12 Jun 2017 15:36:34 +0200 (CEST)
   34.34 +X-RZG-FWD-BY: pep.test.recip@kgrothoff.org
   34.35 +Received: from mailin.rzone.de ([unix socket])
   34.36 +	by mailin.rzone.de (RZmta 40.9) with LMTPA;
   34.37 +	Mon, 12 Jun 2017 15:36:18 +0200 (CEST)
   34.38 +Authentication-Results: strato.com 1;
   34.39 +	spf=none
   34.40 +		smtp.mailfrom="pep.test.alice@pep-project.org";
   34.41 +	dkim=none;
   34.42 +	domainkeys=none;
   34.43 +	dkim-adsp=none
   34.44 +		header.from="pep.test.alice@pep-project.org"
   34.45 +X-Strato-MessageType: email
   34.46 +X-RZG-CLASS-ID: mi00
   34.47 +Received-SPF: none
   34.48 +	client-ip=131.159.0.8;
   34.49 +	helo="mail-out1.informatik.tu-muenchen.de";
   34.50 +	envelope-from="pep.test.alice@pep-project.org";
   34.51 +	receiver=smtpin.rzone.de;
   34.52 +	identity=mailfrom;
   34.53 +Received: from mail-out1.informatik.tu-muenchen.de ([131.159.0.8])
   34.54 +	by smtpin.rzone.de (RZmta 40.9 OK)
   34.55 +	with ESMTPS id p044e9t5CDaIXCz
   34.56 +	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA))
   34.57 +	(Client did not present a certificate)
   34.58 +	for <pep.test.recip@kgrothoff.org>;
   34.59 +	Mon, 12 Jun 2017 15:36:18 +0200 (CEST)
   34.60 +Received: from [192.168.178.22] (ip5f584089.dynamic.kabel-deutschland.de [95.88.64.137])
   34.61 +	by services.sec.in.tum.de (Postfix) with ESMTPSA id D40EB1013AE4F
   34.62 +	for <pep.test.recip@kgrothoff.org>; Mon, 12 Jun 2017 15:36:12 +0200 (CEST)
   34.63 +To: pep.test.recip@kgrothoff.org
   34.64 +Reply-To: krista@pep-project.org
   34.65 +From: pEp Test Alice <pep.test.alice@pep-project.org>
   34.66 +Subject: pEp
   34.67 +Organization: pEp
   34.68 +Message-ID: <7b251ab6-f1c0-163b-0891-574d4eb095e1@pep-project.org>
   34.69 +Date: Mon, 12 Jun 2017 15:36:12 +0200
   34.70 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101
   34.71 + Thunderbird/45.8.0
   34.72 +MIME-Version: 1.0
   34.73 +Content-Type: text/plain; charset=utf-8
   34.74 +Content-Transfer-Encoding: 7bit
   34.75 +
   34.76 +Unencrypted variable where pEp is the actual subject.
    35.1 --- a/test/test_util.cc	Mon May 08 15:48:46 2017 +0200
    35.2 +++ b/test/test_util.cc	Wed Jun 28 13:33:53 2017 +0200
    35.3 @@ -1,4 +1,6 @@
    35.4  #include "pEpEngine_test.h"
    35.5 +#include "pEpEngine.h"
    35.6 +#include "message_api.h"
    35.7  #include <fstream>
    35.8  #include <sstream>
    35.9  #include <stdexcept>
   35.10 @@ -15,3 +17,237 @@
   35.11  	sstr << input.rdbuf();
   35.12  	return sstr.str();
   35.13  }
   35.14 +
   35.15 +const char* tl_status_string(PEP_STATUS status) {
   35.16 +    switch (status) {
   35.17 +        case PEP_STATUS_OK:
   35.18 +            return "PEP_STATUS_OK";
   35.19 +        case PEP_INIT_CANNOT_LOAD_GPGME:
   35.20 +            return "PEP_INIT_CANNOT_LOAD_GPGME";
   35.21 +        case PEP_INIT_GPGME_INIT_FAILED:
   35.22 +            return "PEP_INIT_GPGME_INIT_FAILED";
   35.23 +        case PEP_INIT_NO_GPG_HOME:
   35.24 +            return "PEP_INIT_NO_GPG_HOME";
   35.25 +        case PEP_INIT_NETPGP_INIT_FAILED:
   35.26 +            return "PEP_INIT_NETPGP_INIT_FAILED";
   35.27 +        case PEP_INIT_SQLITE3_WITHOUT_MUTEX:
   35.28 +            return "PEP_INIT_SQLITE3_WITHOUT_MUTEX";
   35.29 +        case PEP_INIT_CANNOT_OPEN_DB:
   35.30 +            return "PEP_INIT_CANNOT_OPEN_DB";
   35.31 +        case PEP_INIT_CANNOT_OPEN_SYSTEM_DB:
   35.32 +            return "PEP_INIT_CANNOT_OPEN_SYSTEM_DB";
   35.33 +        case PEP_KEY_NOT_FOUND:
   35.34 +            return "PEP_KEY_NOT_FOUND";
   35.35 +        case PEP_KEY_HAS_AMBIG_NAME:
   35.36 +            return "PEP_KEY_HAS_AMBIG_NAME";
   35.37 +        case PEP_GET_KEY_FAILED:
   35.38 +            return "PEP_GET_KEY_FAILED";
   35.39 +        case PEP_CANNOT_EXPORT_KEY:
   35.40 +            return "PEP_CANNOT_EXPORT_KEY";
   35.41 +        case PEP_CANNOT_EDIT_KEY:
   35.42 +            return "PEP_CANNOT_EDIT_KEY";
   35.43 +        case PEP_CANNOT_FIND_IDENTITY:
   35.44 +            return "PEP_CANNOT_FIND_IDENTITY";
   35.45 +        case PEP_CANNOT_SET_PERSON:
   35.46 +            return "PEP_CANNOT_SET_PERSON";
   35.47 +        case PEP_CANNOT_SET_PGP_KEYPAIR:
   35.48 +            return "PEP_CANNOT_SET_PGP_KEYPAIR";
   35.49 +        case PEP_CANNOT_SET_IDENTITY:
   35.50 +            return "PEP_CANNOT_SET_IDENTITY";
   35.51 +        case PEP_CANNOT_SET_TRUST:
   35.52 +            return "PEP_CANNOT_SET_TRUST";
   35.53 +        case PEP_KEY_BLACKLISTED:
   35.54 +            return "PEP_KEY_BLACKLISTED";
   35.55 +        case PEP_UNENCRYPTED:
   35.56 +            return "PEP_UNENCRYPTED";
   35.57 +        case PEP_VERIFIED:
   35.58 +            return "PEP_VERIFIED";
   35.59 +        case PEP_DECRYPTED:
   35.60 +            return "PEP_DECRYPTED";
   35.61 +        case PEP_DECRYPTED_AND_VERIFIED:
   35.62 +            return "PEP_DECRYPTED_AND_VERIFIED";
   35.63 +        case PEP_DECRYPT_WRONG_FORMAT:
   35.64 +            return "PEP_DECRYPT_WRONG_FORMAT";
   35.65 +        case PEP_DECRYPT_NO_KEY:
   35.66 +            return "PEP_DECRYPT_NO_KEY";
   35.67 +        case PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH:
   35.68 +            return "PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH";
   35.69 +        case PEP_VERIFY_NO_KEY:
   35.70 +            return "PEP_VERIFY_NO_KEY";
   35.71 +        case PEP_VERIFIED_AND_TRUSTED:
   35.72 +            return "PEP_VERIFIED_AND_TRUSTED";
   35.73 +        case PEP_CANNOT_DECRYPT_UNKNOWN:
   35.74 +            return "PEP_CANNOT_DECRYPT_UNKNOWN";
   35.75 +        case PEP_TRUSTWORD_NOT_FOUND:
   35.76 +            return "PEP_TRUSTWORD_NOT_FOUND";
   35.77 +        case PEP_TRUSTWORDS_FPR_WRONG_LENGTH:
   35.78 +            return "PEP_TRUSTWORDS_FPR_WRONG_LENGTH";
   35.79 +        case PEP_CANNOT_CREATE_KEY:
   35.80 +            return "PEP_CANNOT_CREATE_KEY";
   35.81 +        case PEP_CANNOT_SEND_KEY:
   35.82 +            return "PEP_CANNOT_SEND_KEY";
   35.83 +        case PEP_PHRASE_NOT_FOUND:
   35.84 +            return "PEP_PHRASE_NOT_FOUND";
   35.85 +        case PEP_SEND_FUNCTION_NOT_REGISTERED:
   35.86 +            return "PEP_SEND_FUNCTION_NOT_REGISTERED";
   35.87 +        case PEP_CONTRAINTS_VIOLATED:
   35.88 +            return "PEP_CONTRAINTS_VIOLATED";
   35.89 +        case PEP_CANNOT_ENCODE:
   35.90 +            return "PEP_CANNOT_ENCODE";
   35.91 +        case PEP_SYNC_NO_NOTIFY_CALLBACK:
   35.92 +            return "PEP_SYNC_NO_NOTIFY_CALLBACK";
   35.93 +        case PEP_SYNC_ILLEGAL_MESSAGE:
   35.94 +            return "PEP_SYNC_ILLEGAL_MESSAGE";
   35.95 +        case PEP_SYNC_NO_INJECT_CALLBACK:
   35.96 +            return "PEP_SYNC_NO_INJECT_CALLBACK";
   35.97 +        case PEP_SEQUENCE_VIOLATED:
   35.98 +            return "PEP_SEQUENCE_VIOLATED";
   35.99 +        case PEP_CANNOT_INCREASE_SEQUENCE:
  35.100 +            return "PEP_CANNOT_INCREASE_SEQUENCE";
  35.101 +        case PEP_CANNOT_SET_SEQUENCE_VALUE:
  35.102 +            return "PEP_CANNOT_SET_SEQUENCE_VALUE";
  35.103 +        case PEP_OWN_SEQUENCE:
  35.104 +            return "PEP_OWN_SEQUENCE";
  35.105 +        case PEP_SYNC_STATEMACHINE_ERROR:
  35.106 +            return "PEP_SYNC_STATEMACHINE_ERROR";
  35.107 +        case PEP_SYNC_NO_TRUST:
  35.108 +            return "PEP_SYNC_NO_TRUST";
  35.109 +        case PEP_STATEMACHINE_INVALID_STATE:
  35.110 +            return "PEP_STATEMACHINE_INVALID_STATE";
  35.111 +        case PEP_STATEMACHINE_INVALID_EVENT:
  35.112 +            return "PEP_STATEMACHINE_INVALID_EVENT";
  35.113 +        case PEP_STATEMACHINE_INVALID_CONDITION:
  35.114 +            return "PEP_STATEMACHINE_INVALID_CONDITION";
  35.115 +        case PEP_STATEMACHINE_INVALID_ACTION:
  35.116 +            return "PEP_STATEMACHINE_INVALID_ACTION";
  35.117 +        case PEP_STATEMACHINE_INHIBITED_EVENT:
  35.118 +            return "PEP_STATEMACHINE_INHIBITED_EVENT";
  35.119 +        case PEP_COMMIT_FAILED:
  35.120 +            return "PEP_COMMIT_FAILED";
  35.121 +        case PEP_MESSAGE_CONSUME:
  35.122 +            return "PEP_MESSAGE_CONSUME";
  35.123 +        case PEP_MESSAGE_IGNORE:
  35.124 +            return "PEP_MESSAGE_IGNORE";
  35.125 +        case PEP_RECORD_NOT_FOUND:
  35.126 +            return "PEP_RECORD_NOT_FOUND";
  35.127 +        case PEP_CANNOT_CREATE_TEMP_FILE:
  35.128 +            return "PEP_CANNOT_CREATE_TEMP_FILE";
  35.129 +        case PEP_ILLEGAL_VALUE:
  35.130 +            return "PEP_ILLEGAL_VALUE";
  35.131 +        case PEP_BUFFER_TOO_SMALL:
  35.132 +            return "PEP_BUFFER_TOO_SMALL";
  35.133 +        case PEP_OUT_OF_MEMORY:
  35.134 +            return "PEP_OUT_OF_MEMORY";
  35.135 +        case PEP_UNKNOWN_ERROR:
  35.136 +            return "PEP_UNKNOWN_ERROR";
  35.137 +        default:
  35.138 +            return "PEP_STATUS_OMGWTFBBQ - This means you're using a status the test lib doesn't know about!";
  35.139 +    }
  35.140 +}
  35.141 +const char* tl_rating_string(PEP_rating rating) {
  35.142 +    switch (rating) {
  35.143 +        case PEP_rating_undefined:
  35.144 +            return "PEP_rating_undefined";
  35.145 +        case PEP_rating_cannot_decrypt:
  35.146 +            return "PEP_rating_cannot_decrypt";
  35.147 +        case PEP_rating_have_no_key:
  35.148 +            return "PEP_rating_have_no_key";
  35.149 +        case PEP_rating_unencrypted:
  35.150 +            return "PEP_rating_unencrypted";
  35.151 +        case PEP_rating_unencrypted_for_some:
  35.152 +            return "PEP_rating_unencrypted_for_some";
  35.153 +        case PEP_rating_unreliable:
  35.154 +            return "PEP_rating_unreliable";
  35.155 +        case PEP_rating_reliable:
  35.156 +            return "PEP_rating_reliable";
  35.157 +        case PEP_rating_trusted:
  35.158 +            return "PEP_rating_trusted";
  35.159 +        case PEP_rating_trusted_and_anonymized:
  35.160 +            return "PEP_rating_trusted_and_anonymized";
  35.161 +        case PEP_rating_fully_anonymous:
  35.162 +            return "PEP_rating_fully_anonymous";
  35.163 +        case PEP_rating_mistrust:
  35.164 +            return "PEP_rating_mistrust";
  35.165 +        case PEP_rating_b0rken:
  35.166 +            return "PEP_rating_b0rken";
  35.167 +        case PEP_rating_under_attack:
  35.168 +            return "PEP_rating_under_attack";
  35.169 +        default:
  35.170 +            return "PEP_rating_OMGWTFBBQ - in other words, INVALID RATING VALUE!!!\n\nSomething bad is going on here, or a new rating value has been added to the enum and not the test function.";
  35.171 +    }
  35.172 +}
  35.173 +
  35.174 +const char* tl_ct_string(PEP_comm_type ct) {
  35.175 +    switch (ct) {
  35.176 +        case PEP_ct_unknown:
  35.177 +            return "PEP_ct_unknown";
  35.178 +        case PEP_ct_no_encryption:
  35.179 +            return "PEP_ct_no_encryption";
  35.180 +        case PEP_ct_no_encrypted_channel:
  35.181 +            return "PEP_ct_no_encrypted_channel";
  35.182 +        case PEP_ct_key_not_found:
  35.183 +            return "PEP_ct_key_not_found";
  35.184 +        case PEP_ct_key_expired:
  35.185 +            return "PEP_ct_key_expired";
  35.186 +        case PEP_ct_key_revoked:
  35.187 +            return "PEP_ct_key_revoked";
  35.188 +        case PEP_ct_key_b0rken:
  35.189 +            return "PEP_ct_key_b0rken";
  35.190 +        case PEP_ct_my_key_not_included:
  35.191 +            return "PEP_ct_my_key_not_included";
  35.192 +        case PEP_ct_security_by_obscurity:
  35.193 +            return "PEP_ct_security_by_obscurity";
  35.194 +        case PEP_ct_b0rken_crypto:
  35.195 +            return "PEP_ct_b0rken_crypto";
  35.196 +        case PEP_ct_key_too_short:
  35.197 +            return "PEP_ct_key_too_short";
  35.198 +        case PEP_ct_compromized:
  35.199 +            return "PEP_ct_compromized";
  35.200 +        case PEP_ct_mistrusted:
  35.201 +            return "PEP_ct_mistrusted";
  35.202 +        case PEP_ct_unconfirmed_encryption:
  35.203 +            return "PEP_ct_unconfirmed_encryption";
  35.204 +        case PEP_ct_OpenPGP_weak_unconfirmed:
  35.205 +            return "PEP_ct_OpenPGP_weak_unconfirmed";
  35.206 +        case PEP_ct_to_be_checked:
  35.207 +            return "PEP_ct_to_be_checked";
  35.208 +        case PEP_ct_SMIME_unconfirmed:
  35.209 +            return "PEP_ct_SMIME_unconfirmed";
  35.210 +        case PEP_ct_CMS_unconfirmed:
  35.211 +            return "PEP_ct_CMS_unconfirmed";
  35.212 +        case PEP_ct_strong_but_unconfirmed:
  35.213 +            return "PEP_ct_strong_but_unconfirmed";
  35.214 +        case PEP_ct_OpenPGP_unconfirmed:
  35.215 +            return "PEP_ct_OpenPGP_unconfirmed";
  35.216 +        case PEP_ct_OTR_unconfirmed:
  35.217 +            return "PEP_ct_OTR_unconfirmed";
  35.218 +        case PEP_ct_unconfirmed_enc_anon:
  35.219 +            return "PEP_ct_unconfirmed_enc_anon";
  35.220 +        case PEP_ct_pEp_unconfirmed:
  35.221 +            return "PEP_ct_pEp_unconfirmed";
  35.222 +        case PEP_ct_confirmed:
  35.223 +            return "PEP_ct_pEp_confirmed";
  35.224 +        case PEP_ct_confirmed_encryption:
  35.225 +            return "PEP_ct_confirmed_encryption";
  35.226 +        case PEP_ct_OpenPGP_weak:
  35.227 +            return "PEP_ct_OpenPGP_weak";
  35.228 +        case PEP_ct_to_be_checked_confirmed:
  35.229 +            return "PEP_ct_to_be_checked_confirmed";
  35.230 +        case PEP_ct_SMIME:
  35.231 +            return "PEP_ct_SMIME";
  35.232 +        case PEP_ct_CMS:
  35.233 +            return "PEP_ct_CMS";
  35.234 +        case PEP_ct_strong_encryption:
  35.235 +            return "PEP_ct_strong_encryption";
  35.236 +        case PEP_ct_OpenPGP:
  35.237 +            return "PEP_ct_OpenPGP";
  35.238 +        case PEP_ct_OTR:
  35.239 +            return "PEP_ct_OTR";
  35.240 +        case PEP_ct_confirmed_enc_anon:
  35.241 +            return "PEP_ct_confirmed_enc_anon";
  35.242 +        case PEP_ct_pEp:
  35.243 +            return "PEP_ct_pEp";
  35.244 +        default:
  35.245 +            return "PEP_ct_OMGWTFBBQ\n\nIn other words, comm type is invalid. Either something's corrupt or a new ct value has been added to the enum but not to the test function.";
  35.246 +    }
  35.247 +}
    36.1 --- a/test/test_util.h	Mon May 08 15:48:46 2017 +0200
    36.2 +++ b/test/test_util.h	Wed Jun 28 13:33:53 2017 +0200
    36.3 @@ -1,5 +1,16 @@
    36.4  #include <string>
    36.5 +#include "pEpEngine.h"
    36.6 +#include "message_api.h"
    36.7  
    36.8  // reads a whole file and returns it as std::string
    36.9  // throws std::runtime_error() if the file cannot be read. Empty file is not an error.
   36.10  std::string slurp(const std::string& filename);
   36.11 +
   36.12 +// Returns the string value of the input rating enum value. 
   36.13 +const char* tl_rating_string(PEP_rating rating);
   36.14 +
   36.15 +// Returns the string value of the input comm_type enum value. 
   36.16 +const char* tl_ct_string(PEP_comm_type ct);
   36.17 +
   36.18 +// Returns the string value of the input status enum value. 
   36.19 +const char* tl_status_string(PEP_STATUS status);
    37.1 --- a/test/trustwords_test.cc	Mon May 08 15:48:46 2017 +0200
    37.2 +++ b/test/trustwords_test.cc	Wed Jun 28 13:33:53 2017 +0200
    37.3 @@ -14,6 +14,7 @@
    37.4      cout << "\n*** get_trustwords test ***\n\n";
    37.5  
    37.6      PEP_SESSION session = nullptr;
    37.7 +    PEP_STATUS status;
    37.8      
    37.9      cout << "calling init()\n";
   37.10      PEP_STATUS status1 = init(&session);
   37.11 @@ -55,29 +56,33 @@
   37.12      assert(words1);
   37.13      cout << words1 << "\n";
   37.14  
   37.15 +    free(words1);
   37.16 +    words1 = nullptr;
   37.17 +    
   37.18      cout << "\nfinding German trustwords for " << fingerprint2 << "...\n";
   37.19      trustwords(session, fingerprint2.c_str(), "de", &words2, &wsize2, 5);
   37.20      assert(words2);
   37.21      cout << words2 << "\n";
   37.22  
   37.23 +    free(words2);
   37.24 +    words1 = nullptr;
   37.25 +
   37.26      cout << "\nfinding German trustwords for " << identity1->address << " and " << identity2->address << "...\n";
   37.27      get_trustwords(session, identity1, identity2, "de", &full_wordlist, &wsize_full, false);
   37.28      assert(full_wordlist);
   37.29      cout << full_wordlist << "\n";
   37.30  
   37.31 -    cout << "\nfinding Englis trustwords for " << identity1->address << " and " << identity2->address << "... with spaces\n";
   37.32 +    free(full_wordlist);
   37.33 +    full_wordlist = nullptr;
   37.34 +
   37.35 +    cout << "\nfinding English trustwords for " << identity1->address << " and " << identity2->address << "... with spaces\n";
   37.36      get_trustwords(session, identity1, identity2_with_spaces, "en", &full_wordlist, &wsize_full, false);
   37.37      assert(full_wordlist);
   37.38      cout << full_wordlist << "\n";
   37.39 +
   37.40 +    free(full_wordlist);
   37.41 +    full_wordlist = nullptr;
   37.42      
   37.43 -    
   37.44 -    pEp_free(words1);
   37.45 -    words1 = nullptr;
   37.46 -    pEp_free(words2);
   37.47 -    words2 = nullptr;
   37.48 -    pEp_free(full_wordlist);
   37.49 -    full_wordlist = nullptr;
   37.50 -
   37.51      cout << "\nTest 2: fpr1 == fpr1, short" << endl;
   37.52      
   37.53      cout << "\nfinding French trustwords for " << fingerprint2 << "...\n";
   37.54 @@ -86,14 +91,14 @@
   37.55      cout << words1 << "\n";
   37.56          
   37.57      cout << "\nfinding French trustwords for " << identity2->address << " and " << identity2->address << "...\n";
   37.58 -    get_trustwords(session, identity2, identity2, "fr", &full_wordlist, &wsize_full, false);
   37.59 -    assert(full_wordlist);
   37.60 -    cout << full_wordlist << "\n";
   37.61 +    status = get_trustwords(session, identity2, identity2, "fr", &full_wordlist, &wsize_full, false);
   37.62 +    assert(status == PEP_TRUSTWORDS_DUPLICATE_FPR);
   37.63 +    cout << "Discovered duplicate fprs as desired" << endl;
   37.64  
   37.65      cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "... with spaces\n";
   37.66      get_trustwords(session, identity2, identity2_with_spaces, "en", &full_wordlist, &wsize_full, false);
   37.67 -    assert(full_wordlist);
   37.68 -    cout << full_wordlist << "\n";
   37.69 +    assert(status == PEP_TRUSTWORDS_DUPLICATE_FPR);
   37.70 +    cout << "Discovered duplicate fprs as desired" << endl;
   37.71  
   37.72      pEp_free(words1);
   37.73      words1 = nullptr;
   37.74 @@ -112,13 +117,13 @@
   37.75      assert(words2);
   37.76      cout << words2 << "\n";
   37.77      
   37.78 -    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "...\n";
   37.79 +    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity1->address << "...\n";
   37.80      get_trustwords(session, identity2, identity1, "en", &full_wordlist, &wsize_full, true);
   37.81      assert(full_wordlist);
   37.82      cout << full_wordlist << "\n";
   37.83      
   37.84 -    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity2->address << "... with spaces\n";
   37.85 -    get_trustwords(session, identity2_with_spaces, identity1, "en", &full_wordlist, &wsize_full, false);
   37.86 +    cout << "\nfinding English trustwords for " << identity2->address << " and " << identity1->address << "... with spaces\n";
   37.87 +    get_trustwords(session, identity2_with_spaces, identity1, "en", &full_wordlist, &wsize_full, true);
   37.88      assert(full_wordlist);
   37.89      cout << full_wordlist << "\n";
   37.90      
   37.91 @@ -199,18 +204,18 @@
   37.92      pEp_free(full_wordlist);
   37.93      full_wordlist = nullptr;
   37.94  
   37.95 -    cout << "\nTest 6: fpr2 is too short" << endl;
   37.96 +    cout << "\nTest 6: fpr2 is shorter" << endl;
   37.97      
   37.98      pEp_identity* identity6 = new_identity(
   37.99          "nobody4@kgrothoff.org",
  37.100 -        "01F932086185C15917B72D30571AFBCA5493553",
  37.101 +        "F1F932086185c15917B72D30571AFBCA5493553",
  37.102          "blargh",
  37.103          "Krista Grothoff");
  37.104      
  37.105      cout << "\nfinding Turkish trustwords for " << identity5->address << " and " << identity6->address << "...\n";
  37.106      PEP_STATUS status6 = get_trustwords(session, identity5, identity6, "tr", &full_wordlist, &wsize_full, false);
  37.107 -    assert(status6 == PEP_TRUSTWORDS_FPR_WRONG_LENGTH);
  37.108 -    cout << "Bad fpr length correctly recognised." << "\n";
  37.109 +    assert(status6 == PEP_STATUS_OK);
  37.110 +    cout << full_wordlist << endl;
  37.111      
  37.112      pEp_identity* identity7 = new_identity(
  37.113          "nobody5@kgrothoff.org",
  37.114 @@ -238,4 +243,3 @@
  37.115      release(session);
  37.116      return 0;
  37.117  }
  37.118 -