Urgh. Fixing bad merge (???)
authorKrista Bennett <krista@pep-project.org>
Mon, 29 Jan 2018 12:15:51 +0100
changeset 246185c8e5aad3bc
parent 2378 b244047cdacc
child 2462 48b526a0daac
child 2463 c1f2f4a80078
Urgh. Fixing bad merge (???)
build-mac/pEpEngine.xcodeproj/project.pbxproj
default.conf
src/Makefile
src/blacklist.h
src/bloblist.c
src/bloblist.h
src/keymanagement.c
src/keymanagement.h
src/message_api.c
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/pEp_string.c
src/pEp_string.h
src/pgp_gpg.c
src/pgp_gpg.h
src/platform_windows.h
src/sync_actions.c
src/sync_impl.c
src/timestamp.c
test/apple_mail_test.cc
test/blacklist_test.cc
test/case_and_dot_address_test.cc
test/decorate_test.cc
test/encrypt_for_identity_test.cc
test/encrypt_missing_private_key_test.cc
test/external_revoke_test.cc
test/identity_list_test.cc
test/least_color_group_test.cc
test/least_common_denom_color_test.cc
test/message_2.0_test.cc
test/message_api_test.cc
test/mistrust_undo_test.cc
test/new_update_id_and_myself_test.cc
test/pEp_subject_received_test.cc
test/revoke_regen_attach_test.cc
test/test_keys/priv/bernd.das.brot-0xCAFAA422_priv.asc
test/test_keys/priv/pep-test-recip-0x08DB0AEE_priv.asc
test/test_keys/priv/pep.test.alexander-0x26B54E4E_priv.asc
test/test_keys/priv/pep.test.bella-0xAF516AAE_priv.asc
test/test_keys/pub/bernd.das.brot-0xCAFAA422_pub.asc
test/test_keys/pub/pep-test-recip-0x08DB0AEE_pub.asc
test/test_keys/pub/pep.test.alexander-0x26B54E4E_pub.asc
test/test_keys/pub/pep.test.bella-0xAF516AAE_pub.asc
test/test_util.cc
test/test_util.h
test/trust_manipulation_test.cc
test/userid_alias_test.cc
     1.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Jan 15 12:26:14 2018 +0100
     1.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Jan 29 12:15:51 2018 +0100
     1.3 @@ -7,6 +7,8 @@
     1.4  	objects = {
     1.5  
     1.6  /* Begin PBXBuildFile section */
     1.7 +		430BCC482015EE800077E998 /* pEp_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 430BCC462015EE800077E998 /* pEp_string.h */; };
     1.8 +		430BCC492015EE800077E998 /* pEp_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 430BCC472015EE800077E998 /* pEp_string.c */; };
     1.9  		430D258B1C9ED75A00B94535 /* blacklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 430D258A1C9ED75A00B94535 /* blacklist.c */; };
    1.10  		4354FF651D6EDF300033069C /* sync_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF641D6EDF300033069C /* sync_impl.c */; };
    1.11  		4354FF691D6EE1A70033069C /* NULL.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF681D6EE1A70033069C /* NULL.c */; };
    1.12 @@ -189,6 +191,8 @@
    1.13  /* End PBXCopyFilesBuildPhase section */
    1.14  
    1.15  /* Begin PBXFileReference section */
    1.16 +		430BCC462015EE800077E998 /* pEp_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pEp_string.h; path = ../src/pEp_string.h; sourceTree = "<group>"; };
    1.17 +		430BCC472015EE800077E998 /* pEp_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pEp_string.c; path = ../src/pEp_string.c; sourceTree = "<group>"; };
    1.18  		430D258A1C9ED75A00B94535 /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../src/blacklist.c; sourceTree = "<group>"; };
    1.19  		4346F86A1ECB38E700381CBE /* sync_app.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sync_app.h; path = ../src/sync_app.h; sourceTree = "<group>"; };
    1.20  		4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
    1.21 @@ -508,6 +512,8 @@
    1.22  		64A8264B1B455C5600EECAF0 /* srcref */ = {
    1.23  			isa = PBXGroup;
    1.24  			children = (
    1.25 +				430BCC472015EE800077E998 /* pEp_string.c */,
    1.26 +				430BCC462015EE800077E998 /* pEp_string.h */,
    1.27  				43F6921C1F164A47009418F5 /* resource_id.c */,
    1.28  				43BA0F451D7964750059172F /* asn1_helper.c */,
    1.29  				4354FF641D6EDF300033069C /* sync_impl.c */,
    1.30 @@ -617,6 +623,7 @@
    1.31  				646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */,
    1.32  				64A8268C1B455D9D00EECAF0 /* pEpEngine.h in Headers */,
    1.33  				646C41091D510CD800C63EFF /* constr_TYPE.h in Headers */,
    1.34 +				430BCC482015EE800077E998 /* pEp_string.h in Headers */,
    1.35  				646C410D1D510CD800C63EFF /* der_encoder.h in Headers */,
    1.36  				646C41231D510CD800C63EFF /* NativeEnumerated.h in Headers */,
    1.37  				646C41071D510CD800C63EFF /* constr_SET_OF.h in Headers */,
    1.38 @@ -852,6 +859,7 @@
    1.39  				646C412A1D510CD800C63EFF /* per_encoder.c in Sources */,
    1.40  				646C412E1D510CD800C63EFF /* per_support.c in Sources */,
    1.41  				64A826781B455D0800EECAF0 /* bloblist.c in Sources */,
    1.42 +				430BCC492015EE800077E998 /* pEp_string.c in Sources */,
    1.43  				646C41041D510CD800C63EFF /* constr_SEQUENCE.c in Sources */,
    1.44  				64A826881B455D0800EECAF0 /* timestamp.c in Sources */,
    1.45  				646C41221D510CD800C63EFF /* NativeEnumerated.c in Sources */,
     2.1 --- a/default.conf	Mon Jan 15 12:26:14 2018 +0100
     2.2 +++ b/default.conf	Mon Jan 29 12:15:51 2018 +0100
     2.3 @@ -99,7 +99,7 @@
     2.4          CFLAGS+= -w
     2.5      endif
     2.6      ifdef DEBUG
     2.7 -        CFLAGS+= -Og -ggdb -DDEBUG_ERRORSTACK
     2.8 +        CFLAGS+= -g -ggdb -DDEBUG_ERRORSTACK
     2.9      else
    2.10          CFLAGS+= -O3 -DNDEBUG
    2.11      endif
    2.12 @@ -148,7 +148,7 @@
    2.13          CXXFLAGS+= -w
    2.14      endif
    2.15      ifdef DEBUG
    2.16 -        CXXFLAGS+= -Og -ggdb
    2.17 +        CXXFLAGS+= -g -ggdb
    2.18      else
    2.19          CXXFLAGS+= -O3 -DNDEBUG
    2.20      endif
     3.1 --- a/src/Makefile	Mon Jan 15 12:26:14 2018 +0100
     3.2 +++ b/src/Makefile	Mon Jan 29 12:15:51 2018 +0100
     3.3 @@ -87,7 +87,10 @@
     3.4  	mkdir -p "$(PREFIX)/lib/"
     3.5  	cp $< $(PREFIX)/lib/
     3.6  	mkdir -p $(PREFIX)/include/pEp
     3.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 sync_app.h blacklist.h openpgp_compat.h $(PREFIX)/include/pEp/
     3.8 +	cp -v pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h \
     3.9 +	      timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
    3.10 +	      cryptotech.h sync.h sync_fsm.h sync_app.h blacklist.h pEp_string.h \
    3.11 +	      openpgp_compat.h $(PREFIX)/include/pEp/
    3.12  
    3.13  .PHONY: uninstall
    3.14  uninstall:
     4.1 --- a/src/blacklist.h	Mon Jan 15 12:26:14 2018 +0100
     4.2 +++ b/src/blacklist.h	Mon Jan 29 12:15:51 2018 +0100
     4.3 @@ -14,6 +14,13 @@
     4.4  //  parameters:
     4.5  //      session (in)        session to use
     4.6  //      fpr (in)            fingerprint of key to blacklist
     4.7 +//
     4.8 +//  caveat:
     4.9 +//      there is no point in blacklisting an own key; for any own
    4.10 +//      identity, this will be ignored. The correct function to use
    4.11 +//      for own keys in this event is "key_reset_trust".
    4.12 +//      Also, this is only effective for OpenPGP-level trust. If
    4.13 +//      this key is for a pEp user, the blacklist is ignored.
    4.14  
    4.15  DYNAMIC_API PEP_STATUS blacklist_add(PEP_SESSION session, const char *fpr);
    4.16  
     5.1 --- a/src/bloblist.c	Mon Jan 15 12:26:14 2018 +0100
     5.2 +++ b/src/bloblist.c	Mon Jan 29 12:15:51 2018 +0100
     5.3 @@ -1,17 +1,17 @@
     5.4  // This file is under GNU General Public License 3.0
     5.5  // see LICENSE.txt
     5.6  
     5.7 -#include "pEp_internal.h"
     5.8 -
     5.9 +#include <stdbool.h>
    5.10  #include <stdlib.h>
    5.11  #include <assert.h>
    5.12  #include <string.h>
    5.13  
    5.14 +#include "platform.h"
    5.15  #include "bloblist.h"
    5.16  
    5.17  static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
    5.18 -                          const char* filename) {
    5.19 -    
    5.20 +        const char* filename)
    5.21 +{
    5.22      if (!bloblist)
    5.23          return false;
    5.24          
    5.25 @@ -30,9 +30,8 @@
    5.26         }
    5.27         /* Default behaviour, can be overwritten post-allocation with
    5.28            set_blob_content_disposition */
    5.29 -       if (strstr(filename, "cid://") == filename)
    5.30 +       if (strncmp(filename, "cid://", 6) == 0)
    5.31             bloblist->disposition = PEP_CONTENT_DISP_INLINE;
    5.32 -                        
    5.33      }               
    5.34      
    5.35      if (blob) {
    5.36 @@ -65,7 +64,10 @@
    5.37  
    5.38      while (curr) {
    5.39          bloblist_t *next = curr->next;
    5.40 -        free(curr->value);
    5.41 +        if (curr->release_value)
    5.42 +            curr->release_value(curr->value);
    5.43 +        else
    5.44 +            free(curr->value);
    5.45          free(curr->mime_type);
    5.46          free(curr->filename);
    5.47          free(curr);
    5.48 @@ -126,14 +128,15 @@
    5.49          const char *mime_type, const char *filename)
    5.50  {
    5.51      assert(blob);
    5.52 -    if (blob == NULL)
    5.53 +    if (!blob)
    5.54          return NULL;
    5.55  
    5.56 -    if (bloblist == NULL)
    5.57 +    if (!bloblist)
    5.58          return new_bloblist(blob, size, mime_type, filename);
    5.59  
    5.60 -    if (bloblist->value == NULL) { // empty list
    5.61 -        if (bloblist->next != NULL)
    5.62 +    if (!bloblist->value) { // empty list
    5.63 +        assert(!bloblist->next);
    5.64 +        if (bloblist->next)
    5.65              return NULL; // invalid list
    5.66              
    5.67          if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
    5.68 @@ -145,18 +148,19 @@
    5.69      }
    5.70  
    5.71      bloblist_t* list_curr = bloblist;
    5.72 +    void (*release_value)(char *) = list_curr->release_value;
    5.73  
    5.74      while (list_curr->next)
    5.75          list_curr = list_curr->next;
    5.76  
    5.77      list_curr->next = new_bloblist(blob, size, mime_type, filename);
    5.78 +    list_curr->release_value = release_value;
    5.79  
    5.80      assert(list_curr->next);
    5.81 -    if (list_curr->next == NULL)
    5.82 +    if (!list_curr->next)
    5.83          return NULL;
    5.84  
    5.85      return list_curr->next;
    5.86 -
    5.87  }
    5.88  
    5.89  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
    5.90 @@ -170,7 +174,8 @@
    5.91  }
    5.92  
    5.93  DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
    5.94 -                                      content_disposition_type disposition) {
    5.95 +        content_disposition_type disposition)
    5.96 +{
    5.97      if (blob)                                    
    5.98          blob->disposition = disposition;
    5.99  }
     6.1 --- a/src/bloblist.h	Mon Jan 15 12:26:14 2018 +0100
     6.2 +++ b/src/bloblist.h	Mon Jan 29 12:15:51 2018 +0100
     6.3 @@ -17,15 +17,18 @@
     6.4  } content_disposition_type;
     6.5  
     6.6  typedef struct _bloblist_t {
     6.7 -    char *value;                    // blob
     6.8 -    size_t size;                    // size of blob
     6.9 -    char *mime_type;                // UTF-8 string of MIME type of blob or
    6.10 -                                    // NULL if unknown
    6.11 -    char *filename;                // UTF-8 string of file name of blob or
    6.12 -                                    // NULL if unknown
    6.13 -    content_disposition_type disposition; // default is attachment when allocated
    6.14 -                                          // (see mime.h and RFC2183)
    6.15 -    struct _bloblist_t *next;
    6.16 +    char *value;                        // blob
    6.17 +    size_t size;                        // size of blob
    6.18 +    char *mime_type;                    // UTF-8 string of MIME type of blob or
    6.19 +                                        // NULL if unknown
    6.20 +    char *filename;                     // UTF-8 string of file name of blob or
    6.21 +                                        // NULL if unknown
    6.22 +    content_disposition_type disposition;
    6.23 +                                        // default is attachment when allocated
    6.24 +                                        // (see mime.h and RFC2183)
    6.25 +    struct _bloblist_t *next;           // this is a single linked list
    6.26 +    void (*release_value)(char *);      // pointer to release function;
    6.27 +                                        // pEp_free() if not set
    6.28  } bloblist_t;
    6.29  
    6.30  
    6.31 @@ -43,6 +46,10 @@
    6.32  //  caveat:
    6.33  //      the ownership of the blob goes to the bloblist; mime_type and filename
    6.34  //      are being copied, the originals remain in the ownership of the caller
    6.35 +//
    6.36 +//      if blob is on a different heap then after the call release_value has to
    6.37 +//      be set by the adapter; this is relevant on operating systems with
    6.38 +//      multiple heaps like Microsoft Windows
    6.39  
    6.40  DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    6.41          const char *filename);
    6.42 @@ -69,6 +76,7 @@
    6.43  
    6.44  DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src);
    6.45  
    6.46 +
    6.47  // bloblist_add() - add reference to a blob to bloblist
    6.48  //
    6.49  //  parameters:
    6.50 @@ -87,6 +95,9 @@
    6.51  //      are being copied, the originals remain in the ownership of the caller.
    6.52  //      bloblist input parameter equal to NULL or with value == NULL is a valid
    6.53  //      empty input list.
    6.54 +//
    6.55 +//      If there is release_value set in bloblist it is copied to the added
    6.56 +//      leaf
    6.57  
    6.58  DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
    6.59          const char *mime_type, const char *filename);
    6.60 @@ -102,6 +113,7 @@
    6.61  
    6.62  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
    6.63  
    6.64 +
    6.65  // set_blob_content_disposition() - set blob content disposition and parameters
    6.66  //                                  when necessary
    6.67  //
    6.68 @@ -110,9 +122,7 @@
    6.69  //      disposition (in)        disposition type (see enum)
    6.70  
    6.71  DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
    6.72 -                                              content_disposition_type disposition);
    6.73 -
    6.74 -
    6.75 +        content_disposition_type disposition);
    6.76  
    6.77  
    6.78  #ifdef __cplusplus
     7.1 --- a/src/keymanagement.c	Mon Jan 15 12:26:14 2018 +0100
     7.2 +++ b/src/keymanagement.c	Mon Jan 29 12:15:51 2018 +0100
     7.3 @@ -12,13 +12,35 @@
     7.4  #include "pEp_internal.h"
     7.5  #include "keymanagement.h"
     7.6  
     7.7 +#include "sync_fsm.h"
     7.8  #include "blacklist.h"
     7.9  
    7.10 -#ifndef EMPTYSTR
    7.11 -#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
    7.12 -#endif
    7.13 +#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
    7.14  
    7.15 -#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
    7.16 +static bool key_matches_address(PEP_SESSION session, const char* address,
    7.17 +                                const char* fpr) {
    7.18 +    if (!session || !address || !fpr)
    7.19 +        return false;
    7.20 +    
    7.21 +    bool retval = false;
    7.22 +    stringlist_t *keylist = NULL;
    7.23 +    PEP_STATUS status = find_keys(session, address, &keylist);
    7.24 +    if (status == PEP_STATUS_OK && keylist) {
    7.25 +        stringlist_t* curr = keylist;
    7.26 +        while (curr) {
    7.27 +            if (curr->value) {
    7.28 +                if (strcasecmp(curr->value, fpr)) {
    7.29 +                    retval = true;
    7.30 +                    break;
    7.31 +                }
    7.32 +            }
    7.33 +            curr = curr->next;
    7.34 +        }
    7.35 +    }
    7.36 +    
    7.37 +    free_stringlist(keylist);
    7.38 +    return retval;                             
    7.39 +}
    7.40  
    7.41  PEP_STATUS elect_pubkey(
    7.42          PEP_SESSION session, pEp_identity * identity
    7.43 @@ -33,36 +55,37 @@
    7.44      assert(status != PEP_OUT_OF_MEMORY);
    7.45      if (status == PEP_OUT_OF_MEMORY)
    7.46          return PEP_OUT_OF_MEMORY;
    7.47 +    
    7.48 +    if (!keylist || !keylist->value)
    7.49 +        identity->comm_type = PEP_ct_key_not_found;    
    7.50 +    else {
    7.51 +        stringlist_t *_keylist;
    7.52 +        for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
    7.53 +            PEP_comm_type _comm_type_key;
    7.54  
    7.55 -    stringlist_t *_keylist;
    7.56 -    for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
    7.57 -        PEP_comm_type _comm_type_key;
    7.58 +            status = get_key_rating(session, _keylist->value, &_comm_type_key);
    7.59 +            assert(status != PEP_OUT_OF_MEMORY);
    7.60 +            if (status == PEP_OUT_OF_MEMORY) {
    7.61 +                free_stringlist(keylist);
    7.62 +                return PEP_OUT_OF_MEMORY;
    7.63 +            }
    7.64  
    7.65 -        status = get_key_rating(session, _keylist->value, &_comm_type_key);
    7.66 -        assert(status != PEP_OUT_OF_MEMORY);
    7.67 -        if (status == PEP_OUT_OF_MEMORY) {
    7.68 -            free_stringlist(keylist);
    7.69 -            return PEP_OUT_OF_MEMORY;
    7.70 -        }
    7.71 -
    7.72 -        if (_comm_type_key != PEP_ct_compromized &&
    7.73 -            _comm_type_key != PEP_ct_unknown)
    7.74 -        {
    7.75 -            if (identity->comm_type == PEP_ct_unknown ||
    7.76 -                _comm_type_key > identity->comm_type)
    7.77 +            if (_comm_type_key != PEP_ct_compromized &&
    7.78 +                _comm_type_key != PEP_ct_unknown)
    7.79              {
    7.80 -                bool blacklisted;
    7.81 -                status = blacklist_is_listed(session, _keylist->value, &blacklisted);
    7.82 -                if (status == PEP_STATUS_OK && !blacklisted) {
    7.83 -                    identity->comm_type = _comm_type_key;
    7.84 -                    _fpr = _keylist->value;
    7.85 +                if (identity->comm_type == PEP_ct_unknown ||
    7.86 +                    _comm_type_key > identity->comm_type)
    7.87 +                {
    7.88 +                    bool blacklisted;
    7.89 +                    status = blacklist_is_listed(session, _keylist->value, &blacklisted);
    7.90 +                    if (status == PEP_STATUS_OK && !blacklisted) {
    7.91 +                        identity->comm_type = _comm_type_key;
    7.92 +                        _fpr = _keylist->value;
    7.93 +                    }
    7.94                  }
    7.95              }
    7.96          }
    7.97      }
    7.98 -
    7.99 -    
   7.100 -//    if (_fpr) {
   7.101      free(identity->fpr);
   7.102  
   7.103      identity->fpr = strdup(_fpr);
   7.104 @@ -70,19 +93,345 @@
   7.105          free_stringlist(keylist);
   7.106          return PEP_OUT_OF_MEMORY;
   7.107      }
   7.108 -//    }
   7.109 +    
   7.110      free_stringlist(keylist);
   7.111      return PEP_STATUS_OK;
   7.112  }
   7.113  
   7.114 -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
   7.115 +static PEP_STATUS validate_fpr(PEP_SESSION session, 
   7.116 +                               pEp_identity* ident) {
   7.117 +    
   7.118 +    PEP_STATUS status = PEP_STATUS_OK;
   7.119 +    
   7.120 +    if (!session || !ident || !ident->fpr || !ident->fpr[0])
   7.121 +        return PEP_ILLEGAL_VALUE;    
   7.122 +        
   7.123 +    char* fpr = ident->fpr;
   7.124 +    
   7.125 +    bool has_private = false;
   7.126 +    
   7.127 +    if (ident->me) {
   7.128 +        status = contains_priv_key(session, fpr, &has_private);
   7.129 +        if (status != PEP_STATUS_OK || !has_private)
   7.130 +            return PEP_KEY_UNSUITABLE;
   7.131 +    }
   7.132 +    
   7.133 +    status = get_trust(session, ident);
   7.134 +    if (status != PEP_STATUS_OK)
   7.135 +        ident->comm_type = PEP_ct_unknown;
   7.136 +            
   7.137 +    PEP_comm_type ct = ident->comm_type;
   7.138 +
   7.139 +    if (ct == PEP_ct_unknown) {
   7.140 +        // If status is bad, it's ok, we get the rating
   7.141 +        // we should use then (PEP_ct_unknown)
   7.142 +        get_key_rating(session, fpr, &ct);
   7.143 +        ident->comm_type = ct;
   7.144 +    }
   7.145 +    
   7.146 +    bool revoked, expired;
   7.147 +    bool blacklisted = false;
   7.148 +    
   7.149 +    status = key_revoked(session, fpr, &revoked);    
   7.150 +        
   7.151 +    if (status != PEP_STATUS_OK) {
   7.152 +        return ADD_TO_LOG(status);
   7.153 +    }
   7.154 +    
   7.155 +    if (!revoked) {
   7.156 +        time_t exp_time = (ident->me ? 
   7.157 +                           time(NULL) + (7*24*3600) : time(NULL));
   7.158 +                           
   7.159 +        status = key_expired(session, fpr, 
   7.160 +                             exp_time,
   7.161 +                             &expired);
   7.162 +                             
   7.163 +        assert(status == PEP_STATUS_OK);
   7.164 +        if (status != PEP_STATUS_OK)
   7.165 +            return ADD_TO_LOG(status);
   7.166 +
   7.167 +        if ((ct | PEP_ct_confirmed) == PEP_ct_OpenPGP &&
   7.168 +            !ident->me) {
   7.169 +            status = blacklist_is_listed(session, 
   7.170 +                                         fpr, 
   7.171 +                                         &blacklisted);
   7.172 +                                         
   7.173 +            if (status != PEP_STATUS_OK)
   7.174 +                return ADD_TO_LOG(status);
   7.175 +        }
   7.176 +    }
   7.177 +            
   7.178 +    if (ident->me && (ct >= PEP_ct_strong_but_unconfirmed) && !revoked && expired) {
   7.179 +        // extend key
   7.180 +        timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
   7.181 +        status = renew_key(session, fpr, ts);
   7.182 +        free_timestamp(ts);
   7.183 +
   7.184 +        if (status == PEP_STATUS_OK) {
   7.185 +            // if key is valid (second check because pEp key might be extended above)
   7.186 +            //      Return fpr        
   7.187 +            status = key_expired(session, fpr, time(NULL), &expired);            
   7.188 +            if (status != PEP_STATUS_OK) {
   7.189 +                 ident->comm_type = PEP_ct_key_expired;
   7.190 +                 return ADD_TO_LOG(status);
   7.191 +             }
   7.192 +            // communicate key(?)
   7.193 +        }        
   7.194 +    }
   7.195 +     
   7.196 +    if (revoked) 
   7.197 +        ct = PEP_ct_key_revoked;
   7.198 +    else if (expired)
   7.199 +        ct = PEP_ct_key_expired;        
   7.200 +    else if (blacklisted) { // never true for .me
   7.201 +        ident->comm_type = ct = PEP_ct_key_not_found;
   7.202 +        free(ident->fpr);
   7.203 +            ident->fpr = strdup("");
   7.204 +        status = PEP_KEY_BLACKLISTED;
   7.205 +    }
   7.206 +    
   7.207 +    switch (ct) {
   7.208 +        case PEP_ct_key_expired:
   7.209 +        case PEP_ct_key_revoked:
   7.210 +        case PEP_ct_key_b0rken:
   7.211 +            // delete key from being default key for all users/identities
   7.212 +            status = remove_fpr_as_default(session, fpr);
   7.213 +            status = update_trust_for_fpr(session, 
   7.214 +                                          fpr, 
   7.215 +                                          ct);
   7.216 +            free(ident->fpr);
   7.217 +            ident->fpr = NULL;
   7.218 +            ident->comm_type = ct;            
   7.219 +            status = PEP_KEY_UNSUITABLE;
   7.220 +        default:
   7.221 +            break;
   7.222 +    }            
   7.223 +
   7.224 +    return status;
   7.225 +}
   7.226 +
   7.227 +PEP_STATUS get_user_default_key(PEP_SESSION session, const char* user_id,
   7.228 +                                char** default_key) {
   7.229 +    assert(session);
   7.230 +    assert(user_id);
   7.231 +    
   7.232 +    if (!session || !user_id)
   7.233 +        return PEP_ILLEGAL_VALUE;
   7.234 +
   7.235 +    PEP_STATUS status = PEP_STATUS_OK;
   7.236 +            
   7.237 +    // try to get default key for user_data
   7.238 +    sqlite3_reset(session->get_user_default_key);
   7.239 +    sqlite3_bind_text(session->get_user_default_key, 1, user_id, 
   7.240 +                      -1, SQLITE_STATIC);
   7.241 +    
   7.242 +    const int result = sqlite3_step(session->get_user_default_key);
   7.243 +    char* user_fpr = NULL;
   7.244 +    if (result == SQLITE_ROW) {
   7.245 +        const char* u_fpr =
   7.246 +            (char *) sqlite3_column_text(session->get_user_default_key, 0);
   7.247 +        if (u_fpr)
   7.248 +            user_fpr = strdup(u_fpr);
   7.249 +    }
   7.250 +    else
   7.251 +        status = PEP_GET_KEY_FAILED;
   7.252 +        
   7.253 +    sqlite3_reset(session->get_user_default_key);
   7.254 +    
   7.255 +    *default_key = user_fpr;
   7.256 +    return status;     
   7.257 +}
   7.258 +
   7.259 +// Only call on retrieval of previously stored identity!
   7.260 +// Also, we presume that if the stored_identity was sent in
   7.261 +// without an fpr, there wasn't one in the trust DB for this
   7.262 +// identity.
   7.263 +PEP_STATUS get_valid_pubkey(PEP_SESSION session,
   7.264 +                         pEp_identity* stored_identity,
   7.265 +                         bool* is_identity_default,
   7.266 +                         bool* is_user_default,
   7.267 +                         bool* is_address_default) {
   7.268 +    
   7.269 +    PEP_STATUS status = PEP_STATUS_OK;
   7.270 +
   7.271 +    if (!stored_identity || EMPTYSTR(stored_identity->user_id)
   7.272 +        || !is_identity_default || !is_user_default || !is_address_default)
   7.273 +        return PEP_ILLEGAL_VALUE;
   7.274 +        
   7.275 +    *is_identity_default = *is_user_default = *is_address_default = false;
   7.276 +
   7.277 +    PEP_comm_type first_reject_comm_type = PEP_ct_key_not_found;
   7.278 +    PEP_STATUS first_reject_status = PEP_KEY_NOT_FOUND;
   7.279 +    
   7.280 +    char* stored_fpr = stored_identity->fpr;
   7.281 +    // Input: stored identity retrieved from database
   7.282 +    // if stored identity contains a default key
   7.283 +    if (!EMPTYSTR(stored_fpr)) {
   7.284 +        status = validate_fpr(session, stored_identity);    
   7.285 +        if (status == PEP_STATUS_OK && !EMPTYSTR(stored_identity->fpr)) {
   7.286 +            *is_identity_default = *is_address_default = true;
   7.287 +            return status;
   7.288 +        }
   7.289 +        else if (status != PEP_KEY_NOT_FOUND) {
   7.290 +            first_reject_status = status;
   7.291 +            first_reject_comm_type = stored_identity->comm_type;
   7.292 +        }
   7.293 +    }
   7.294 +    // if no valid default stored identity key found
   7.295 +    free(stored_identity->fpr);
   7.296 +    stored_identity->fpr = NULL;
   7.297 +    
   7.298 +    char* user_fpr = NULL;
   7.299 +    status = get_user_default_key(session, stored_identity->user_id, &user_fpr);
   7.300 +    
   7.301 +    if (!EMPTYSTR(user_fpr)) {             
   7.302 +        // There exists a default key for user, so validate
   7.303 +        stored_identity->fpr = user_fpr;
   7.304 +        status = validate_fpr(session, stored_identity);
   7.305 +        if (status == PEP_STATUS_OK && stored_identity->fpr) {
   7.306 +            *is_user_default = true;
   7.307 +            *is_address_default = key_matches_address(session, 
   7.308 +                                                      stored_identity->address,
   7.309 +                                                      stored_identity->fpr);
   7.310 +            return status;
   7.311 +        }        
   7.312 +        else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
   7.313 +            first_reject_status = status;
   7.314 +            first_reject_comm_type = stored_identity->comm_type;
   7.315 +        }
   7.316 +    }
   7.317 +    
   7.318 +    status = elect_pubkey(session, stored_identity);
   7.319 +    if (status == PEP_STATUS_OK) {
   7.320 +        if (!EMPTYSTR(stored_identity->fpr))
   7.321 +            validate_fpr(session, stored_identity);
   7.322 +    }    
   7.323 +    else if (status != PEP_KEY_NOT_FOUND && first_reject_status != PEP_KEY_NOT_FOUND) {
   7.324 +        first_reject_status = status;
   7.325 +        first_reject_comm_type = stored_identity->comm_type;
   7.326 +    }
   7.327 +    
   7.328 +    switch (stored_identity->comm_type) {
   7.329 +        case PEP_ct_key_revoked:
   7.330 +        case PEP_ct_key_b0rken:
   7.331 +        case PEP_ct_key_expired:
   7.332 +        case PEP_ct_compromized:
   7.333 +        case PEP_ct_mistrusted:
   7.334 +            // this only happens when it's all there is
   7.335 +            status = first_reject_status;
   7.336 +            free(stored_identity->fpr);
   7.337 +            stored_identity->fpr = NULL;
   7.338 +            stored_identity->comm_type = first_reject_comm_type;
   7.339 +            break;    
   7.340 +        default:
   7.341 +            break;
   7.342 +    }
   7.343 +    return status;
   7.344 +}
   7.345 +
   7.346 +static void transfer_ident_lang_and_flags(pEp_identity* new_ident,
   7.347 +                                          pEp_identity* stored_ident) {
   7.348 +    if (new_ident->lang[0] == 0) {
   7.349 +      new_ident->lang[0] = stored_ident->lang[0];
   7.350 +      new_ident->lang[1] = stored_ident->lang[1];
   7.351 +      new_ident->lang[2] = 0;
   7.352 +    }
   7.353 +
   7.354 +    new_ident->flags = stored_ident->flags;
   7.355 +    new_ident->me = new_ident->me || stored_ident->me;
   7.356 +}
   7.357 +
   7.358 +static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
   7.359 +                                                 pEp_identity* return_id,
   7.360 +                                                 pEp_identity* stored_ident,
   7.361 +                                                 bool store) {
   7.362 +    
   7.363 +    if (!session || !return_id || !stored_ident)
   7.364 +        return PEP_ILLEGAL_VALUE;
   7.365 +    
   7.366 +    PEP_STATUS status;
   7.367 +    
   7.368 +    bool is_identity_default, is_user_default, is_address_default;
   7.369 +    status = get_valid_pubkey(session, stored_ident,
   7.370 +                                &is_identity_default,
   7.371 +                                &is_user_default,
   7.372 +                                &is_address_default);
   7.373 +                                
   7.374 +    if (status == PEP_STATUS_OK && stored_ident->fpr && *(stored_ident->fpr) != '\0') {
   7.375 +    // set identity comm_type from trust db (user_id, FPR)
   7.376 +        status = get_trust(session, stored_ident);
   7.377 +        if (status == PEP_CANNOT_FIND_IDENTITY || stored_ident->comm_type == PEP_ct_unknown) {
   7.378 +            // This is OK - there is no trust DB entry, but we
   7.379 +            // found a key. We won't store this, but we'll
   7.380 +            // use it.
   7.381 +            PEP_comm_type ct = PEP_ct_unknown;
   7.382 +            status = get_key_rating(session, stored_ident->fpr, &ct);
   7.383 +            stored_ident->comm_type = ct;
   7.384 +        }
   7.385 +    }
   7.386 +    free(return_id->fpr);
   7.387 +    return_id->fpr = NULL;
   7.388 +    if (status == PEP_STATUS_OK && !EMPTYSTR(stored_ident->fpr))
   7.389 +        return_id->fpr = strdup(stored_ident->fpr);
   7.390 +        
   7.391 +    return_id->comm_type = stored_ident->comm_type;
   7.392 +                
   7.393 +    // We patch the DB with the input username, but if we didn't have
   7.394 +    // one, we pull it out of storage if available.
   7.395 +    // (also, if the input username is "anonymous" and there exists
   7.396 +    //  a DB username, we replace)
   7.397 +    if (!EMPTYSTR(stored_ident->username)) {
   7.398 +        if (!EMPTYSTR(return_id->username) && 
   7.399 +            (strcasecmp(return_id->username, "anonymous") == 0)) {
   7.400 +            free(return_id->username);
   7.401 +            return_id->username = NULL;
   7.402 +        }
   7.403 +        if (EMPTYSTR(return_id->username)) {
   7.404 +            free(return_id->username);
   7.405 +            return_id->username = strdup(stored_ident->username);
   7.406 +        }
   7.407 +    }
   7.408 +    
   7.409 +    return_id->me = stored_ident->me;
   7.410 +    
   7.411 +    // FIXME: Do we ALWAYS do this? We probably should...
   7.412 +    if (EMPTYSTR(return_id->user_id)) {
   7.413 +        free(return_id->user_id);
   7.414 +        return_id->user_id = strdup(stored_ident->user_id);
   7.415 +    }    
   7.416 +    // Call set_identity() to store
   7.417 +    if ((is_identity_default || is_user_default) &&
   7.418 +         is_address_default) {                 
   7.419 +         // if we got an fpr which is default for either user
   7.420 +         // or identity AND is valid for this address, set in DB
   7.421 +         // as default
   7.422 +         status = set_identity(session, return_id);
   7.423 +    }
   7.424 +    else {
   7.425 +        // Store without default fpr/ct, but return the fpr and ct 
   7.426 +        // for current use
   7.427 +        char* save_fpr = return_id->fpr;
   7.428 +        PEP_comm_type save_ct = return_id->comm_type;
   7.429 +        return_id->fpr = NULL;
   7.430 +        return_id->comm_type = PEP_ct_unknown;
   7.431 +        PEP_STATUS save_status = status;
   7.432 +        status = set_identity(session, return_id);
   7.433 +        if (save_status != PEP_STATUS_OK)
   7.434 +            status = save_status;
   7.435 +        return_id->fpr = save_fpr;
   7.436 +        return_id->comm_type = save_ct;
   7.437 +    }
   7.438 +    
   7.439 +    transfer_ident_lang_and_flags(return_id, stored_ident);
   7.440 +    
   7.441 +    return status;
   7.442 +}
   7.443 +
   7.444  
   7.445  DYNAMIC_API PEP_STATUS update_identity(
   7.446          PEP_SESSION session, pEp_identity * identity
   7.447      )
   7.448  {
   7.449 -    pEp_identity *stored_identity = NULL;
   7.450 -    pEp_identity *temp_id = NULL;
   7.451      PEP_STATUS status;
   7.452  
   7.453      assert(session);
   7.454 @@ -92,237 +441,242 @@
   7.455      if (!(session && identity && !EMPTYSTR(identity->address)))
   7.456          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   7.457  
   7.458 -    if (_identity_me(identity)) {
   7.459 -        return _myself(session, identity, false, true);
   7.460 +    char* default_own_id = NULL;
   7.461 +    status = get_default_own_userid(session, &default_own_id);    
   7.462 +
   7.463 +    // Is this me, temporary or not? If so, BAIL.
   7.464 +    if (identity->me || 
   7.465 +       (default_own_id && identity->user_id && (strcmp(default_own_id, identity->user_id) == 0))) 
   7.466 +    {
   7.467 +        return PEP_ILLEGAL_VALUE;
   7.468      }
   7.469  
   7.470 -    int _no_user_id = EMPTYSTR(identity->user_id);
   7.471 -    int _did_elect_new_key = 0;
   7.472 +    // We have, at least, an address.
   7.473 +    // Retrieve stored identity information!    
   7.474 +    pEp_identity* stored_ident = NULL;
   7.475  
   7.476 -    if (_no_user_id)
   7.477 -    {
   7.478 -        status = get_identity(session, identity->address, PEP_OWN_USERID,
   7.479 -                &stored_identity);
   7.480 -        if (status == PEP_STATUS_OK) {
   7.481 -            free_identity(stored_identity);
   7.482 -            return _myself(session, identity, false, true);
   7.483 +    if (!EMPTYSTR(identity->user_id)) {            
   7.484 +        // (we're gonna update the trust/fpr anyway, so we use the no-fpr-from-trust-db variant)
   7.485 +        //      * do get_identity() to retrieve stored identity information
   7.486 +        status = get_identity_without_trust_check(session, identity->address, identity->user_id, &stored_ident);
   7.487 +
   7.488 +        // Before we start - if there was no stored identity, we should check to make sure we don't
   7.489 +        // have a stored identity with a temporary user_id that differs from the input user_id. This
   7.490 +        // happens in multithreaded environments sometimes.
   7.491 +        if (!stored_ident) {
   7.492 +            identity_list* id_list = NULL;
   7.493 +            status = get_identities_by_address(session, identity->address, &id_list);
   7.494 +
   7.495 +            if (id_list) {
   7.496 +                identity_list* id_curr = id_list;
   7.497 +                while (id_curr) {
   7.498 +                    pEp_identity* this_id = id_curr->ident;
   7.499 +                    if (this_id) {
   7.500 +                        char* this_uid = this_id->user_id;
   7.501 +                        if (this_uid && (strstr(this_uid, "TOFU_") == this_uid)) {
   7.502 +                            // FIXME: should we also be fixing pEp_own_userId in this
   7.503 +                            // function here?
   7.504 +                            
   7.505 +                            // if usernames match, we replace the userid. Or if the temp username
   7.506 +                            // is anonymous.
   7.507 +                            if (EMPTYSTR(this_id->username) ||
   7.508 +                                strcasecmp(this_id->username, "anonymous") == 0 ||
   7.509 +                                (identity->username && 
   7.510 +                                 strcasecmp(identity->username, 
   7.511 +                                            this_id->username) == 0)) {
   7.512 +                                
   7.513 +                                // Ok, we have a temp ID. We have to replace this
   7.514 +                                // with the real ID.
   7.515 +                                status = replace_userid(session, 
   7.516 +                                                        this_uid, 
   7.517 +                                                        identity->user_id);
   7.518 +                                if (status != PEP_STATUS_OK) {
   7.519 +                                    free_identity_list(id_list);
   7.520 +                                    return status;
   7.521 +                                }
   7.522 +                                    
   7.523 +                                free(this_uid);
   7.524 +                                this_uid = NULL;
   7.525 +                                
   7.526 +                                // Reflect the change we just made to the DB
   7.527 +                                this_id->user_id = strdup(identity->user_id);
   7.528 +                                stored_ident = this_id;
   7.529 +                                // FIXME: free list.
   7.530 +                                break;                                
   7.531 +                            }                            
   7.532 +                        } 
   7.533 +                    }
   7.534 +                    id_curr = id_curr->next;
   7.535 +                }
   7.536 +            }
   7.537 +        } 
   7.538 +                
   7.539 +        if (status == PEP_STATUS_OK && stored_ident) { 
   7.540 +            //  * if identity available
   7.541 +            //      * patch it with username
   7.542 +            //          (note: this will happen when 
   7.543 +            //           setting automatically below...)
   7.544 +            //      * elect valid key for identity
   7.545 +            //    * if valid key exists
   7.546 +            //        * set return value's fpr
   7.547 +            status = prepare_updated_identity(session,
   7.548 +                                              identity,
   7.549 +                                              stored_ident, true);
   7.550          }
   7.551 +        //  * else (identity unavailable)
   7.552 +        else {
   7.553 +            status = PEP_STATUS_OK;
   7.554 +            
   7.555 +            //  if we only have user_id and address and identity not available
   7.556 +            //      * return error status (identity not found)
   7.557 +            if (EMPTYSTR(identity->username))
   7.558 +                status = PEP_CANNOT_FIND_IDENTITY;
   7.559 +            
   7.560 +            // Otherwise, if we had user_id, address, and username:
   7.561 +            //    * create identity with user_id, address, username
   7.562 +            //      (this is the input id without the fpr + comm type!)
   7.563 +            free(identity->fpr);
   7.564 +            identity->fpr = NULL;
   7.565 +            identity->comm_type = PEP_ct_unknown;
   7.566 +            
   7.567 +            //    * We've already checked and retrieved
   7.568 +            //      any applicable temporary identities above. If we're 
   7.569 +            //      here, none of them fit.
   7.570 +            //    * call set_identity() to store
   7.571 +            if (status == PEP_STATUS_OK) {
   7.572 +                status = set_identity(session, identity);
   7.573 +                if (status == PEP_STATUS_OK) {
   7.574 +                    elect_pubkey(session, identity);
   7.575 +                }
   7.576 +            }
   7.577 +            //  * Return: created identity
   7.578 +        }        
   7.579 +    }
   7.580 +    else if (!EMPTYSTR(identity->username)) {
   7.581 +        /*
   7.582 +         * Temporary identity information with username supplied
   7.583 +            * Input: address, username (no others)
   7.584 +         */
   7.585 +         
   7.586 +        //  * See if there is an own identity that uses this address. If so, we'll
   7.587 +        //    prefer that
   7.588 +        stored_ident = NULL;
   7.589 +        
   7.590 +        if (default_own_id) {
   7.591 +            status = get_identity(session, 
   7.592 +                                  default_own_id, 
   7.593 +                                  identity->address, 
   7.594 +                                  &stored_ident);
   7.595 +        }
   7.596 +        // If there isn't an own identity, search for a non-temp stored ident
   7.597 +        // with this address.                      
   7.598 +        if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) { 
   7.599 + 
   7.600 +            identity_list* id_list = NULL;
   7.601 +            status = get_identities_by_address(session, identity->address, &id_list);
   7.602  
   7.603 -        free(identity->user_id);
   7.604 -
   7.605 -        identity->user_id = calloc(1, strlen(identity->address) + 6);
   7.606 -        if (!identity->user_id)
   7.607 -        {
   7.608 -            return PEP_OUT_OF_MEMORY;
   7.609 -        }
   7.610 -        snprintf(identity->user_id, strlen(identity->address) + 6,
   7.611 -                 "TOFU_%s", identity->address);
   7.612 -    }
   7.613 - 
   7.614 -    status = get_identity(session,
   7.615 -                          identity->address,
   7.616 -                          identity->user_id,
   7.617 -                          &stored_identity);
   7.618 -    
   7.619 -    assert(status != PEP_OUT_OF_MEMORY);
   7.620 -    if (status == PEP_OUT_OF_MEMORY)
   7.621 -        goto exit_free;
   7.622 -
   7.623 -    temp_id = identity_dup(identity);
   7.624 -    
   7.625 -    /* We don't take given fpr. 
   7.626 -       In case there's no acceptable stored fpr, it will be elected. */
   7.627 -    free(temp_id->fpr);
   7.628 -    temp_id->fpr = NULL;
   7.629 -    temp_id->comm_type = PEP_ct_unknown;
   7.630 -            
   7.631 -    if (stored_identity) {
   7.632 -        
   7.633 -        bool dont_use_stored_fpr = true;
   7.634 -
   7.635 -        /* if we have a stored_identity fpr */
   7.636 -        if (!EMPTYSTR(stored_identity->fpr)) {
   7.637 -            bool revoked = false;
   7.638 -            status = key_revoked(session, stored_identity->fpr, &revoked);
   7.639 -            
   7.640 -            if (status != PEP_STATUS_OK || revoked)
   7.641 -                dont_use_stored_fpr = true;
   7.642 -                
   7.643 -            if (revoked) {
   7.644 -                // Do stuff
   7.645 -                status = update_trust_for_fpr(session, stored_identity->fpr, PEP_ct_key_revoked);
   7.646 -                // What to do on failure? FIXME
   7.647 -                status = replace_identities_fpr(session, stored_identity->fpr, "");
   7.648 -            }
   7.649 -            else {    
   7.650 -                status = blacklist_is_listed(session, stored_identity->fpr, &dont_use_stored_fpr);
   7.651 -                if (status != PEP_STATUS_OK)
   7.652 -                    dont_use_stored_fpr = true; 
   7.653 -            }
   7.654 -        }
   7.655 -            
   7.656 -
   7.657 -        if (!dont_use_stored_fpr) {
   7.658 -            /* Check stored comm_type */
   7.659 -            PEP_comm_type _comm_type_key;
   7.660 -            status = get_key_rating(session, stored_identity->fpr, &_comm_type_key);
   7.661 -            assert(status != PEP_OUT_OF_MEMORY);
   7.662 -            if (status == PEP_OUT_OF_MEMORY) {
   7.663 -                goto exit_free;
   7.664 -            }
   7.665 -            if (status == PEP_KEY_NOT_FOUND){
   7.666 -                /* stored key was deleted from keyring. any other candidate ?*/
   7.667 -                status = elect_pubkey(session, temp_id);
   7.668 -                if (status != PEP_STATUS_OK) {
   7.669 -                    goto exit_free;
   7.670 -                } else {
   7.671 -                    _did_elect_new_key = 1;
   7.672 -                }
   7.673 -            } else {
   7.674 -                temp_id->fpr = strdup(stored_identity->fpr);
   7.675 -                assert(temp_id->fpr);
   7.676 -                if (temp_id->fpr == NULL) {
   7.677 -                    status = PEP_OUT_OF_MEMORY;
   7.678 -                    goto exit_free;
   7.679 -                }
   7.680 -
   7.681 -                if (_comm_type_key < PEP_ct_unconfirmed_encryption) {
   7.682 -                    /* if key not good anymore, 
   7.683 -                       downgrade eventually trusted comm_type */
   7.684 -                    temp_id->comm_type = _comm_type_key;
   7.685 -                } else {
   7.686 -                    /* otherwise take stored comm_type as-is except if 
   7.687 -                       is unknown or is expired (but key not expired anymore) */
   7.688 -                    temp_id->comm_type = stored_identity->comm_type;
   7.689 -                    if (temp_id->comm_type == PEP_ct_unknown ||
   7.690 -                        temp_id->comm_type == PEP_ct_key_expired) {
   7.691 -                        temp_id->comm_type = _comm_type_key;
   7.692 +            if (id_list) {
   7.693 +                identity_list* id_curr = id_list;
   7.694 +                while (id_curr) {
   7.695 +                    pEp_identity* this_id = id_curr->ident;
   7.696 +                    if (this_id) {
   7.697 +                        char* this_uid = this_id->user_id;
   7.698 +                        if (this_uid && (strstr(this_uid, "TOFU_") != this_uid)) {
   7.699 +                            // if usernames match, we replace the userid.
   7.700 +                            if (identity->username && 
   7.701 +                                strcasecmp(identity->username, 
   7.702 +                                           this_id->username) == 0) {
   7.703 +                                
   7.704 +                                // Ok, we have a real ID. Copy it!
   7.705 +                                identity->user_id = strdup(this_uid);
   7.706 +                                
   7.707 +                                if (!identity->user_id)
   7.708 +                                    status = PEP_OUT_OF_MEMORY;
   7.709 +                                stored_ident = this_id;
   7.710 +                                
   7.711 +                                break;                                
   7.712 +                            }                            
   7.713 +                        } 
   7.714                      }
   7.715 +                    id_curr = id_curr->next;
   7.716                  }
   7.717              }
   7.718          }
   7.719 +        
   7.720 +        if (stored_ident) {
   7.721 +            status = prepare_updated_identity(session,
   7.722 +                                              identity,
   7.723 +                                              stored_ident, true);
   7.724 +        }
   7.725          else {
   7.726 -            status = elect_pubkey(session, temp_id);
   7.727 -            if (status != PEP_STATUS_OK){
   7.728 -                goto exit_free;
   7.729 -            } else {
   7.730 -                _did_elect_new_key = 1;
   7.731 -            }
   7.732 -        }
   7.733 -        
   7.734 -        /* ok, from here on out, use temp_id */
   7.735 -        
   7.736 -        
   7.737 -        /* At this point, we either have a non-blacklisted fpr we can work */
   7.738 -        /* with, or we've got nada.                                        */
   7.739 +            // create temporary identity, store it, and Return this
   7.740 +            // This means TOFU_ user_id
   7.741 +            identity->user_id = calloc(1, strlen(identity->address) + 6);
   7.742 +            if (!identity->user_id)
   7.743 +                return PEP_OUT_OF_MEMORY;
   7.744  
   7.745 -        if (EMPTYSTR(temp_id->fpr)) {
   7.746 -            /* nada : set comm_type accordingly */
   7.747 -            temp_id->comm_type = PEP_ct_key_not_found;
   7.748 -        }
   7.749 -        
   7.750 -        if (EMPTYSTR(temp_id->username)) {
   7.751 -            free(temp_id->username);
   7.752 -            temp_id->username = strdup(stored_identity->username);
   7.753 -            assert(temp_id->username);
   7.754 -            if (temp_id->username == NULL){
   7.755 -                status = PEP_OUT_OF_MEMORY;
   7.756 -                goto exit_free;
   7.757 -            }
   7.758 -        }
   7.759 -
   7.760 -        if (temp_id->lang[0] == 0) {
   7.761 -            temp_id->lang[0] = stored_identity->lang[0];
   7.762 -            temp_id->lang[1] = stored_identity->lang[1];
   7.763 -            temp_id->lang[2] = 0;
   7.764 -        }
   7.765 -
   7.766 -        temp_id->flags = stored_identity->flags;
   7.767 -    }
   7.768 -    else /* stored_identity == NULL */ {
   7.769 -        temp_id->flags = 0;
   7.770 -
   7.771 -        /* We elect a pubkey */
   7.772 -        status = elect_pubkey(session, temp_id);
   7.773 -        if (status != PEP_STATUS_OK)
   7.774 -            goto exit_free;
   7.775 -        
   7.776 -        /* Work with the elected key */
   7.777 -        if (!EMPTYSTR(temp_id->fpr)) {
   7.778 +            snprintf(identity->user_id, strlen(identity->address) + 6,
   7.779 +                     "TOFU_%s", identity->address);        
   7.780              
   7.781 -            PEP_comm_type _comm_type_key = temp_id->comm_type;
   7.782 -            
   7.783 -            _did_elect_new_key = 1;
   7.784 -
   7.785 -            // We don't want to lose a previous trust entry!!!
   7.786 -            status = get_trust(session, temp_id);
   7.787 -
   7.788 -            bool has_trust_status = (status == PEP_STATUS_OK);
   7.789 -
   7.790 -            if (!has_trust_status)
   7.791 -                temp_id->comm_type = _comm_type_key;
   7.792 -        }
   7.793 -    }
   7.794 -
   7.795 -    if (temp_id->fpr == NULL) {
   7.796 -        temp_id->fpr = strdup("");
   7.797 -        if (temp_id->fpr == NULL) {
   7.798 -            status = PEP_OUT_OF_MEMORY;
   7.799 -            goto exit_free;
   7.800 -        }
   7.801 -    }
   7.802 -    
   7.803 -    
   7.804 -    status = PEP_STATUS_OK;
   7.805 -
   7.806 -    if (temp_id->comm_type != PEP_ct_unknown && !EMPTYSTR(temp_id->user_id)) {
   7.807 -
   7.808 -        if (EMPTYSTR(temp_id->username)) { // mitigate
   7.809 -            free(temp_id->username);
   7.810 -            temp_id->username = strdup("anonymous");
   7.811 -            assert(temp_id->username);
   7.812 -            if (temp_id->username == NULL){
   7.813 -                status = PEP_OUT_OF_MEMORY;
   7.814 -                goto exit_free;
   7.815 -            }
   7.816 -        }
   7.817 -
   7.818 -        // Identity doesn't get stored if call was just about checking existing
   7.819 -        // user by address (i.e. no user id given but already stored)
   7.820 -        if (!(_no_user_id && stored_identity) || _did_elect_new_key)
   7.821 -        {
   7.822 -            status = set_identity(session, temp_id);
   7.823 -            assert(status == PEP_STATUS_OK);
   7.824 -            if (status != PEP_STATUS_OK) {
   7.825 -                goto exit_free;
   7.826 +            free(identity->fpr);
   7.827 +            identity->fpr = NULL;
   7.828 +            identity->comm_type = PEP_ct_unknown;
   7.829 +             
   7.830 +            //    * We've already checked and retrieved
   7.831 +            //      any applicable temporary identities above. If we're 
   7.832 +            //      here, none of them fit.
   7.833 +            //    * call set_identity() to store
   7.834 +            status = set_identity(session, identity);
   7.835 +            if (status == PEP_STATUS_OK) {
   7.836 +                elect_pubkey(session, identity);
   7.837              }
   7.838          }
   7.839      }
   7.840 +    else {
   7.841 +        /*
   7.842 +         * Temporary identity information without username suplied
   7.843 +            * Input: address (no others)
   7.844 +         */
   7.845 +         
   7.846 +        //  * Again, see if there is an own identity that uses this address. If so, we'll
   7.847 +        //    prefer that
   7.848 +        stored_ident = NULL;
   7.849 +         
   7.850 +        if (default_own_id) {
   7.851 +            status = get_identity(session, 
   7.852 +                                  default_own_id, 
   7.853 +                                  identity->address, 
   7.854 +                                  &stored_ident);
   7.855 +        }
   7.856 +        // If there isn't an own identity, search for a non-temp stored ident
   7.857 +        // with this address.                      
   7.858 +        if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) { 
   7.859 + 
   7.860 +            identity_list* id_list = NULL;
   7.861 +            status = get_identities_by_address(session, identity->address, &id_list);
   7.862  
   7.863 -    if (temp_id->comm_type != PEP_ct_compromized &&
   7.864 -            temp_id->comm_type < PEP_ct_strong_but_unconfirmed)
   7.865 +            //    * Search for identity with this address
   7.866 +            if (id_list && !(id_list->next)) { // exactly one            
   7.867 +                //    * If exactly one found
   7.868 +                //      * elect valid key for identity (see below)
   7.869 +                //      * Return this identity
   7.870 +                stored_ident = id_list->ident;
   7.871 +            }
   7.872 +        }
   7.873 +        if (stored_ident)
   7.874 +            status = prepare_updated_identity(session, identity,
   7.875 +                                              stored_ident, false);
   7.876 +        else // too little info
   7.877 +            status = PEP_CANNOT_FIND_IDENTITY; 
   7.878 +    }
   7.879 +    
   7.880 +    // FIXME: This is legacy. I presume it's a notification for the caller...
   7.881 +    // Revisit once I can talk to Volker
   7.882 +    if (identity->comm_type != PEP_ct_compromized &&
   7.883 +        identity->comm_type < PEP_ct_strong_but_unconfirmed)
   7.884          if (session->examine_identity)
   7.885 -            session->examine_identity(temp_id, session->examine_management);
   7.886 -    
   7.887 -    /* ok, we got to the end. So we can assign the output identity */
   7.888 -    free(identity->address);
   7.889 -    identity->address = strdup(temp_id->address);
   7.890 -    free(identity->fpr);
   7.891 -    identity->fpr = strdup(temp_id->fpr);
   7.892 -    free(identity->user_id);
   7.893 -    identity->user_id = strdup(temp_id->user_id);
   7.894 -    free(identity->username);
   7.895 -    identity->username = strdup(temp_id->username ? temp_id->username : "anonymous");
   7.896 -    identity->comm_type = temp_id->comm_type;
   7.897 -    identity->lang[0] = temp_id->lang[0];
   7.898 -    identity->lang[1] = temp_id->lang[1];
   7.899 -    identity->lang[2] = 0;
   7.900 -    identity->flags = temp_id->flags;
   7.901 +            session->examine_identity(identity, session->examine_management);
   7.902  
   7.903 -exit_free :
   7.904 -    free_identity(stored_identity);
   7.905 -    free_identity(temp_id);
   7.906 -    
   7.907      return ADD_TO_LOG(status);
   7.908  }
   7.909  
   7.910 @@ -418,206 +772,189 @@
   7.911  
   7.912  PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags)
   7.913  {
   7.914 -    pEp_identity *stored_identity = NULL;
   7.915 +
   7.916      PEP_STATUS status;
   7.917  
   7.918      assert(session);
   7.919      assert(identity);
   7.920      assert(!EMPTYSTR(identity->address));
   7.921 +    assert(!EMPTYSTR(identity->user_id));
   7.922  
   7.923 -    assert(EMPTYSTR(identity->user_id) ||
   7.924 -           strcmp(identity->user_id, PEP_OWN_USERID) == 0);
   7.925 -
   7.926 -    if (!(session && identity && !EMPTYSTR(identity->address) &&
   7.927 -            (EMPTYSTR(identity->user_id) ||
   7.928 -            strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
   7.929 +    if (!session || !identity || EMPTYSTR(identity->address) ||
   7.930 +        EMPTYSTR(identity->user_id))
   7.931          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   7.932  
   7.933 +    pEp_identity *stored_identity = NULL;
   7.934 +    char* revoked_fpr = NULL; 
   7.935 +        
   7.936 +    char* default_own_id = NULL;
   7.937 +    status = get_default_own_userid(session, &default_own_id);
   7.938 +
   7.939 +    // Deal with non-default user_ids.
   7.940 +    if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
   7.941 +        
   7.942 +        status = set_userid_alias(session, default_own_id, identity->user_id);
   7.943 +        // Do we want this to be fatal? For now, we'll do it...
   7.944 +        if (status != PEP_STATUS_OK)
   7.945 +            goto pep_free;
   7.946 +            
   7.947 +        free(identity->user_id);
   7.948 +        identity->user_id = strdup(default_own_id);
   7.949 +        if (identity->user_id == NULL) {
   7.950 +            status = PEP_OUT_OF_MEMORY;
   7.951 +            goto pep_free;
   7.952 +        }
   7.953 +    }
   7.954 +
   7.955 +    // NOTE: IF WE DON'T YET HAVE AN OWN_ID, WE IGNORE REFERENCES TO THIS ADDRESS IN THE
   7.956 +    // DB (WHICH MAY HAVE BEEN SET BEFORE MYSELF WAS CALLED BY RECEIVING AN EMAIL FROM
   7.957 +    // THIS ADDRESS), AS IT IS NOT AN OWN_IDENTITY AND HAS NO INFORMATION WE NEED OR WHAT TO
   7.958 +    // SET FOR MYSELF
   7.959 +    
   7.960 +    // Ok, so now, set up the own_identity:
   7.961      identity->comm_type = PEP_ct_pEp;
   7.962 +    identity->me = true;
   7.963      if(ignore_flags)
   7.964          identity->flags = 0;
   7.965      
   7.966 -    if (EMPTYSTR(identity->user_id))
   7.967 -    {
   7.968 -        free(identity->user_id);
   7.969 -        identity->user_id = strdup(PEP_OWN_USERID);
   7.970 -        assert(identity->user_id);
   7.971 -        if (identity->user_id == NULL)
   7.972 -            return PEP_OUT_OF_MEMORY;
   7.973 -    }
   7.974 -
   7.975 -    if (EMPTYSTR(identity->username))
   7.976 -    {
   7.977 -        free(identity->username);
   7.978 -        identity->username = strdup("anonymous");
   7.979 -        assert(identity->username);
   7.980 -        if (identity->username == NULL)
   7.981 -            return PEP_OUT_OF_MEMORY;
   7.982 -    }
   7.983 -
   7.984 +    // Let's see if we have an identity record in the DB for 
   7.985 +    // this user_id + address
   7.986      DEBUG_LOG("myself", "debug", identity->address);
   7.987   
   7.988      status = get_identity(session,
   7.989                            identity->address,
   7.990                            identity->user_id,
   7.991                            &stored_identity);
   7.992 -    
   7.993 +
   7.994      assert(status != PEP_OUT_OF_MEMORY);
   7.995      if (status == PEP_OUT_OF_MEMORY)
   7.996          return PEP_OUT_OF_MEMORY;
   7.997  
   7.998 -    bool dont_use_stored_fpr = true;
   7.999 -    bool dont_use_input_fpr = true;
  7.1000 +    // Set usernames - priority is input username > stored name > "Anonymous"
  7.1001 +    // If there's an input username, we always patch the username with that
  7.1002 +    // input.
  7.1003 +    if (EMPTYSTR(identity->username)) {
  7.1004 +        bool stored_uname = (stored_identity && stored_identity->username);
  7.1005 +        char* uname = (stored_uname ? stored_identity->username : "Anonymous");
  7.1006 +        free(identity->username);
  7.1007 +        identity->username = strdup(uname);
  7.1008 +        if (identity->username == NULL)
  7.1009 +            return PEP_OUT_OF_MEMORY;
  7.1010 +    }
  7.1011 +
  7.1012 +    bool valid_key_found = false;
  7.1013 +    
  7.1014 +    // Now deal with keys.
  7.1015 +    // Different from update_identity(), the input fpr here
  7.1016 +    // MATTERS. 
  7.1017 +    // If the input fpr is invalid, we return, giving the reason why.
  7.1018 +    if (!EMPTYSTR(identity->fpr)) {
  7.1019 +        status = validate_fpr(session, identity);
  7.1020 +    
  7.1021 +        if (status != PEP_STATUS_OK || 
  7.1022 +            identity->comm_type < PEP_ct_strong_but_unconfirmed) {
  7.1023 +            if (identity->comm_type != PEP_ct_key_expired)
  7.1024 +                goto pep_free;
  7.1025 +            // Otherwise, it was expired and key renewal failed
  7.1026 +            // and we take the stored one or do keygen. 
  7.1027 +        } 
  7.1028 +        else
  7.1029 +            valid_key_found = true;
  7.1030 +    }    
  7.1031 +    
  7.1032 +    // Ok, if there wasn't a valid input fpr, check stored identity
  7.1033 +    if (!valid_key_found && stored_identity && 
  7.1034 +        (EMPTYSTR(identity->fpr) || strcmp(stored_identity->fpr, identity->fpr) != 0)) {
  7.1035          
  7.1036 -    if (stored_identity)
  7.1037 -    {
  7.1038 -        if (EMPTYSTR(identity->fpr)) {
  7.1039 -            
  7.1040 -            bool has_private = false;
  7.1041 -            
  7.1042 -            status = _has_usable_priv_key(session, stored_identity->fpr, &has_private); 
  7.1043 -            
  7.1044 -            // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
  7.1045 -            if (has_private) {
  7.1046 -                identity->fpr = strdup(stored_identity->fpr);
  7.1047 -                assert(identity->fpr);
  7.1048 -                if (identity->fpr == NULL)
  7.1049 -                {
  7.1050 -                    return PEP_OUT_OF_MEMORY;
  7.1051 -                }
  7.1052 -                dont_use_stored_fpr = false;
  7.1053 -            }
  7.1054 +        // Fall back / retrieve
  7.1055 +        status = validate_fpr(session, stored_identity);
  7.1056 +        if (status == PEP_STATUS_OK && 
  7.1057 +            stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
  7.1058 +          
  7.1059 +            free(identity->fpr);
  7.1060 +            identity->fpr = strdup(stored_identity->fpr);
  7.1061 +            valid_key_found = true;            
  7.1062          }
  7.1063 -        
  7.1064 -        identity->flags = (identity->flags & 255) | stored_identity->flags;
  7.1065 -        free_identity(stored_identity);
  7.1066 -    }
  7.1067 -    
  7.1068 -    if (dont_use_stored_fpr && !EMPTYSTR(identity->fpr))
  7.1069 -    {
  7.1070 -        // App must have a good reason to give fpr, such as explicit
  7.1071 -        // import of private key, or similar.
  7.1072 -
  7.1073 -        // Take given fpr as-is.
  7.1074 -
  7.1075 -        // BUT:
  7.1076 -        // First check to see if it's blacklisted or private part is missing?
  7.1077 -        bool has_private = false;
  7.1078 -        
  7.1079 -        status = _has_usable_priv_key(session, identity->fpr, &has_private); 
  7.1080 -        
  7.1081 -        // N.B. has_private is never true if the returned status is not PEP_STATUS_OK
  7.1082 -        if (has_private) {
  7.1083 -            dont_use_input_fpr = false;
  7.1084 +        else {
  7.1085 +            bool revoked = false;
  7.1086 +            if (!EMPTYSTR(stored_identity->fpr)) {
  7.1087 +                status = key_revoked(session, stored_identity->fpr, &revoked);
  7.1088 +                if (revoked)
  7.1089 +                    revoked_fpr = strdup(stored_identity->fpr);
  7.1090 +            }        
  7.1091          }
  7.1092      }
  7.1093      
  7.1094 -    // Ok, we failed to get keys either way, so let's elect one.
  7.1095 -    if (dont_use_input_fpr && dont_use_stored_fpr)
  7.1096 -    {
  7.1097 -        status = elect_ownkey(session, identity);
  7.1098 -        assert(status == PEP_STATUS_OK);
  7.1099 -        if (status != PEP_STATUS_OK) {
  7.1100 -            return ADD_TO_LOG(status);
  7.1101 -        }
  7.1102 +    // Nothing left to do but generate a key
  7.1103 +    if (!valid_key_found) {
  7.1104 +        if (!do_keygen)
  7.1105 +            status = PEP_GET_KEY_FAILED;
  7.1106 +        else {
  7.1107 +            DEBUG_LOG("Generating key pair", "debug", identity->address);
  7.1108  
  7.1109 -        bool has_private = false;
  7.1110 -        if (identity->fpr) {
  7.1111 -            // ok, we elected something.
  7.1112 -            // elect_ownkey only returns private keys, so we don't check again.
  7.1113 -            // Check to see if it's blacklisted
  7.1114 -            bool listed;
  7.1115 -            status = blacklist_is_listed(session, identity->fpr, &listed); 
  7.1116 +            free(identity->fpr);
  7.1117 +            identity->fpr = NULL;
  7.1118 +            status = generate_keypair(session, identity);
  7.1119 +            assert(status != PEP_OUT_OF_MEMORY);
  7.1120  
  7.1121 -            if (status == PEP_STATUS_OK)
  7.1122 -                has_private = !listed;
  7.1123 -        }
  7.1124 -        
  7.1125 -        if (has_private) {
  7.1126 -            dont_use_input_fpr = false;
  7.1127 -        }
  7.1128 -        else { // OK, we've tried everything. Time to generate new keys.
  7.1129 -            free(identity->fpr); // It can stay in this state (unallocated) because we'll generate a new key 
  7.1130 -            identity->fpr = NULL;
  7.1131 +            if (status != PEP_STATUS_OK) {
  7.1132 +                char buf[11];
  7.1133 +                snprintf(buf, 11, "%d", status); // uh, this is kludgey. FIXME
  7.1134 +                DEBUG_LOG("Generating key pair failed", "debug", buf);
  7.1135 +            }        
  7.1136 +            else {
  7.1137 +                valid_key_found = true;
  7.1138 +                if (revoked_fpr) {
  7.1139 +                    status = set_revoked(session, revoked_fpr,
  7.1140 +                                         stored_identity->fpr, time(NULL));
  7.1141 +                }
  7.1142 +            }
  7.1143          }
  7.1144      }
  7.1145  
  7.1146 -    bool revoked = false;
  7.1147 -    char *r_fpr = NULL;
  7.1148 -    if (!EMPTYSTR(identity->fpr))
  7.1149 -    {
  7.1150 -        status = key_revoked(session, identity->fpr, &revoked);
  7.1151 +    if (valid_key_found) {
  7.1152 +        identity->comm_type = PEP_ct_pEp;
  7.1153 +        status = PEP_STATUS_OK;
  7.1154 +    }
  7.1155 +    else {
  7.1156 +        free(identity->fpr);
  7.1157 +        identity->fpr = NULL;
  7.1158 +        identity->comm_type = PEP_ct_unknown;
  7.1159 +    }
  7.1160 +    
  7.1161 +    status = set_identity(session, identity);
  7.1162  
  7.1163 -        if (status != PEP_STATUS_OK) 
  7.1164 -        {
  7.1165 -            return ADD_TO_LOG(status);
  7.1166 -        }
  7.1167 -    }
  7.1168 -   
  7.1169 -    if (EMPTYSTR(identity->fpr) || revoked)
  7.1170 -    {
  7.1171 -        if(!do_keygen){
  7.1172 -            return ADD_TO_LOG(PEP_GET_KEY_FAILED);
  7.1173 +pep_free:    
  7.1174 +    free(default_own_id);
  7.1175 +    free(revoked_fpr);                     
  7.1176 +    free_identity(stored_identity);
  7.1177 +    return ADD_TO_LOG(status);
  7.1178 +}
  7.1179 +
  7.1180 +DYNAMIC_API PEP_STATUS initialise_own_identities(PEP_SESSION session,
  7.1181 +                                                 identity_list* my_idents) {
  7.1182 +    PEP_STATUS status = PEP_STATUS_OK;
  7.1183 +    if (!session)
  7.1184 +        return PEP_ILLEGAL_VALUE;
  7.1185 +        
  7.1186 +    if (!my_idents)
  7.1187 +        return PEP_STATUS_OK;
  7.1188 +            
  7.1189 +    identity_list* ident_curr = my_idents;
  7.1190 +    while (ident_curr) {
  7.1191 +        pEp_identity* ident = ident_curr->ident;
  7.1192 +        if (!ident || !ident->address) {
  7.1193 +            status = PEP_ILLEGAL_VALUE;
  7.1194 +            goto pep_error;
  7.1195          }
  7.1196  
  7.1197 -        if(revoked)
  7.1198 -        {
  7.1199 -            r_fpr = identity->fpr;
  7.1200 -            identity->fpr = NULL;
  7.1201 -        }
  7.1202 +        status = _myself(session, ident, false, false);
  7.1203          
  7.1204 -        DEBUG_LOG("generating key pair", "debug", identity->address);
  7.1205 -        status = generate_keypair(session, identity);
  7.1206 -        assert(status != PEP_OUT_OF_MEMORY);
  7.1207 -        if (status != PEP_STATUS_OK) {
  7.1208 -            char buf[11];
  7.1209 -            snprintf(buf, 11, "%d", status);
  7.1210 -            DEBUG_LOG("generating key pair failed", "debug", buf);
  7.1211 -            if(revoked && r_fpr)
  7.1212 -                free(r_fpr);
  7.1213 -            return ADD_TO_LOG(status);
  7.1214 -        }
  7.1215 -
  7.1216 -        
  7.1217 -        if(revoked)
  7.1218 -        {
  7.1219 -            status = set_revoked(session, r_fpr,
  7.1220 -                                 identity->fpr, time(NULL));
  7.1221 -            free(r_fpr);
  7.1222 -            if (status != PEP_STATUS_OK) {
  7.1223 -                return ADD_TO_LOG(status);
  7.1224 -            }
  7.1225 -        }
  7.1226 +        ident_curr = ident_curr->next;
  7.1227      }
  7.1228 -    else
  7.1229 -    {
  7.1230 -        bool expired;
  7.1231 -        status = key_expired(session, identity->fpr, 
  7.1232 -                             time(NULL) + (7*24*3600), // In a week
  7.1233 -                             &expired);
  7.1234 -
  7.1235 -        assert(status == PEP_STATUS_OK);
  7.1236 -        if (status != PEP_STATUS_OK) {
  7.1237 -            return ADD_TO_LOG(status);
  7.1238 -        }
  7.1239 -
  7.1240 -        if (status == PEP_STATUS_OK && expired) {
  7.1241 -            timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
  7.1242 -            renew_key(session, identity->fpr, ts);
  7.1243 -            free_timestamp(ts);
  7.1244 -        }
  7.1245 -    }
  7.1246 -
  7.1247 -    if (!identity->username)
  7.1248 -        identity->username = strdup("");
  7.1249      
  7.1250 -    status = set_identity(session, identity);
  7.1251 -    assert(status == PEP_STATUS_OK);
  7.1252 -    if (status != PEP_STATUS_OK) {
  7.1253 -        return status;
  7.1254 -    }
  7.1255 -
  7.1256 -    return ADD_TO_LOG(PEP_STATUS_OK);
  7.1257 +pep_error:
  7.1258 +    return status;
  7.1259  }
  7.1260  
  7.1261  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
  7.1262 @@ -670,7 +1007,7 @@
  7.1263          {
  7.1264              DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address);
  7.1265  
  7.1266 -            if (_identity_me(identity)) {
  7.1267 +            if (identity->me) {
  7.1268                  status = myself(session, identity);
  7.1269              } else {
  7.1270                  status = recv_key(session, identity->address);
  7.1271 @@ -703,7 +1040,7 @@
  7.1272      if (!(session && ident && ident->fpr))
  7.1273          return PEP_ILLEGAL_VALUE;
  7.1274  
  7.1275 -    if (_identity_me(ident))
  7.1276 +    if (ident->me)
  7.1277      {
  7.1278          revoke_key(session, ident->fpr, NULL);
  7.1279          myself(session, ident);
  7.1280 @@ -714,7 +1051,16 @@
  7.1281          if (session->cached_mistrusted)
  7.1282              free(session->cached_mistrusted);
  7.1283          session->cached_mistrusted = identity_dup(ident);
  7.1284 -        status = mark_as_compromized(session, ident->fpr);
  7.1285 +        
  7.1286 +        // set mistrust for this user_id/keypair (even if there's not an
  7.1287 +        // identity set yet, this is important, as we need to record the mistrust
  7.1288 +        // action)
  7.1289 +        status = set_trust(session, ident->user_id, ident->fpr, PEP_ct_mistrusted);
  7.1290 +        if (status == PEP_STATUS_OK)
  7.1291 +            // cascade that mistrust for anyone using this key
  7.1292 +            status = mark_as_compromized(session, ident->fpr);
  7.1293 +        if (status == PEP_STATUS_OK)
  7.1294 +            status = remove_fpr_as_default(session, ident->fpr);
  7.1295      }
  7.1296  
  7.1297      return status;
  7.1298 @@ -751,30 +1097,70 @@
  7.1299  
  7.1300      assert(session);
  7.1301      assert(ident);
  7.1302 -    assert(!_identity_me(ident));
  7.1303      assert(!EMPTYSTR(ident->fpr));
  7.1304      assert(!EMPTYSTR(ident->address));
  7.1305      assert(!EMPTYSTR(ident->user_id));
  7.1306  
  7.1307 -    if (!(session && ident && !_identity_me(ident) && ident->fpr && ident->address &&
  7.1308 +    if (!(session && ident && ident->fpr && ident->fpr[0] != '\0' && ident->address &&
  7.1309              ident->user_id))
  7.1310          return PEP_ILLEGAL_VALUE;
  7.1311  
  7.1312 -    status = update_identity(session, ident);
  7.1313 +    // we do not change the input struct at ALL.
  7.1314 +    pEp_identity* input_copy = identity_dup(ident);
  7.1315 +    
  7.1316 +    pEp_identity* tmp_ident = NULL;
  7.1317 +    
  7.1318 +    status = get_trust(session, input_copy);
  7.1319 +    
  7.1320      if (status != PEP_STATUS_OK)
  7.1321 -        return status;
  7.1322 +        goto pep_free;
  7.1323 +        
  7.1324 +    PEP_comm_type new_trust = PEP_ct_unknown;
  7.1325  
  7.1326 -    if (ident->comm_type == PEP_ct_mistrusted)
  7.1327 -        ident->comm_type = PEP_ct_unknown;
  7.1328 -    else
  7.1329 -        ident->comm_type &= ~PEP_ct_confirmed;
  7.1330 +    if (input_copy->comm_type != PEP_ct_mistrusted)
  7.1331 +        new_trust = input_copy->comm_type & ~PEP_ct_confirmed;
  7.1332  
  7.1333 -    status = set_identity(session, ident);
  7.1334 +    status = set_trust(session, ident->user_id, ident->fpr, new_trust);
  7.1335 +    
  7.1336      if (status != PEP_STATUS_OK)
  7.1337 -        return status;
  7.1338 +        goto pep_free;
  7.1339  
  7.1340 -    if (ident->comm_type == PEP_ct_unknown)
  7.1341 -        status = update_identity(session, ident);
  7.1342 +        
  7.1343 +    input_copy->comm_type = new_trust;
  7.1344 +        
  7.1345 +    tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
  7.1346 +
  7.1347 +    if (!tmp_ident)
  7.1348 +        return PEP_OUT_OF_MEMORY;
  7.1349 +    
  7.1350 +    status = update_identity(session, tmp_ident);
  7.1351 +    
  7.1352 +    if (status != PEP_STATUS_OK)
  7.1353 +        goto pep_free;
  7.1354 +    
  7.1355 +    // remove as default if necessary
  7.1356 +    if (strcmp(tmp_ident->fpr, ident->fpr) == 0) {
  7.1357 +        free(tmp_ident->fpr);
  7.1358 +        tmp_ident->fpr = NULL;
  7.1359 +        tmp_ident->comm_type = PEP_ct_unknown;
  7.1360 +        status = set_identity(session, tmp_ident);
  7.1361 +        if (status != PEP_STATUS_OK)
  7.1362 +            goto pep_free;
  7.1363 +    }
  7.1364 +    
  7.1365 +    char* user_default = NULL;
  7.1366 +    status = get_main_user_fpr(session, tmp_ident->user_id, &user_default);
  7.1367 +    
  7.1368 +    if (!EMPTYSTR(user_default)) {
  7.1369 +        if (strcmp(user_default, ident->fpr) == 0)
  7.1370 +            status = refresh_userid_default_key(session, ident->user_id);
  7.1371 +        if (status != PEP_STATUS_OK)
  7.1372 +            goto pep_free;    
  7.1373 +    }
  7.1374 +            
  7.1375 +pep_free:
  7.1376 +    free_identity(tmp_ident);
  7.1377 +    free_identity(input_copy);
  7.1378      return status;
  7.1379  }
  7.1380  
  7.1381 @@ -795,18 +1181,99 @@
  7.1382              EMPTYSTR(ident->fpr))
  7.1383          return PEP_ILLEGAL_VALUE;
  7.1384  
  7.1385 -    status = update_identity(session, ident);
  7.1386 -    if (status != PEP_STATUS_OK)
  7.1387 -        return status;
  7.1388 +    //bool ident_has_trusted_default = false;
  7.1389 +    char* ident_default_fpr = NULL;
  7.1390  
  7.1391 -    if (ident->comm_type > PEP_ct_strong_but_unconfirmed) {
  7.1392 -        ident->comm_type |= PEP_ct_confirmed;
  7.1393 -        status = set_identity(session, ident);
  7.1394 -    }
  7.1395 -    else {
  7.1396 -        // MISSING: S/MIME has to be handled depending on trusted CAs
  7.1397 -        status = PEP_CANNOT_SET_TRUST;
  7.1398 -    }
  7.1399 +    // Before we do anything, be sure the input fpr is even eligible to be trusted
  7.1400 +    PEP_comm_type input_default_ct = PEP_ct_unknown;
  7.1401 +    status = get_key_rating(session, ident->fpr, &input_default_ct);
  7.1402 +    if (input_default_ct < PEP_ct_strong_but_unconfirmed)
  7.1403 +        return PEP_KEY_UNSUITABLE;
  7.1404 +
  7.1405 +    // Save the input fpr
  7.1406 +    char* cached_fpr = strdup(ident->fpr);
  7.1407 +    ident->fpr = NULL;
  7.1408 +
  7.1409 +    bool me = is_me(session, ident);
  7.1410 +
  7.1411 +    if (me)
  7.1412 +        return myself(session, ident); // FIXME: Not the right thing if we 
  7.1413 +                                       // don't always replace user default!!!
  7.1414 +
  7.1415 +    // First, set up a temp trusted identity for the input fpr without a comm type;
  7.1416 +    pEp_identity* tmp_id = new_identity(ident->address, cached_fpr, ident->user_id, NULL);
  7.1417 +    status = validate_fpr(session, tmp_id);
  7.1418 +        
  7.1419 +    if (status == PEP_STATUS_OK) {
  7.1420 +        // Validate fpr gets trust DB or, when that fails, key comm type. we checked
  7.1421 +        // above that the key was ok. (not revoked or expired), but we want the max.
  7.1422 +        tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
  7.1423 +                                       
  7.1424 +        // Get the default identity without setting the fpr
  7.1425 +        status = update_identity(session, ident);
  7.1426 +        ident_default_fpr = strdup(ident->fpr);
  7.1427 +
  7.1428 +        if (status == PEP_STATUS_OK) {
  7.1429 +            bool trusted_default = false;
  7.1430 +
  7.1431 +            // If there's no default, or the default is different from the input...
  7.1432 +            if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
  7.1433 +                
  7.1434 +                // If the default fpr (if there is one) is trusted and key is strong enough,
  7.1435 +                // don't replace, we just set the trusted bit on this key for this user_id...
  7.1436 +                // (If there's no default fpr, this won't be true anyway.)
  7.1437 +                if (ident->comm_type >= PEP_ct_strong_but_unconfirmed && 
  7.1438 +                    (ident->comm_type & PEP_ct_confirmed)) {                        
  7.1439 +
  7.1440 +                    trusted_default = true;
  7.1441 +                                    
  7.1442 +                    status = set_trust(session, tmp_id->user_id, cached_fpr, tmp_id->comm_type);
  7.1443 +                    input_default_ct = tmp_id->comm_type;                    
  7.1444 +                }
  7.1445 +                else {
  7.1446 +                    free(ident->fpr);
  7.1447 +                    ident->fpr = strdup(cached_fpr);
  7.1448 +                    ident->comm_type = tmp_id->comm_type;
  7.1449 +                    status = set_identity(session, ident); // replace identity default            
  7.1450 +                }
  7.1451 +            }
  7.1452 +            else { // we're setting this on the default fpr
  7.1453 +                ident->comm_type = tmp_id->comm_type;
  7.1454 +                status = set_identity(session, ident);
  7.1455 +                trusted_default = true;
  7.1456 +            }
  7.1457 +            if (status == PEP_STATUS_OK && !trusted_default) {
  7.1458 +                // Ok, there wasn't a trusted default, so we replaced. Thus, we also
  7.1459 +                // make sure there's a trusted default on the user_id. If there
  7.1460 +                // is not, we make this the default.
  7.1461 +                char* user_default = NULL;
  7.1462 +                status = get_main_user_fpr(session, ident->user_id, &user_default);
  7.1463 +            
  7.1464 +                if (status == PEP_STATUS_OK && user_default) {
  7.1465 +                    pEp_identity* tmp_user_ident = new_identity(ident->address, 
  7.1466 +                                                                user_default, 
  7.1467 +                                                                ident->user_id, 
  7.1468 +                                                                NULL);
  7.1469 +                    if (!tmp_user_ident)
  7.1470 +                        status = PEP_OUT_OF_MEMORY;
  7.1471 +                    else {
  7.1472 +                        status = validate_fpr(session, tmp_user_ident);
  7.1473 +                        
  7.1474 +                        if (status != PEP_STATUS_OK ||
  7.1475 +                            tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
  7.1476 +                            !(tmp_user_ident->comm_type & PEP_ct_confirmed)) 
  7.1477 +                        {
  7.1478 +                            char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
  7.1479 +                            status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
  7.1480 +                        } 
  7.1481 +                    }
  7.1482 +                }
  7.1483 +            }
  7.1484 +        }
  7.1485 +        free(ident_default_fpr);
  7.1486 +        free(cached_fpr);
  7.1487 +        free_identity(tmp_id);
  7.1488 +    }    
  7.1489  
  7.1490      return status;
  7.1491  }
  7.1492 @@ -837,6 +1304,7 @@
  7.1493          case SQLITE_ROW:
  7.1494              count = sqlite3_column_int(session->own_key_is_listed, 0);
  7.1495              *listed = count > 0;
  7.1496 +            status = PEP_STATUS_OK;
  7.1497              break;
  7.1498              
  7.1499          default:
  7.1500 @@ -886,14 +1354,15 @@
  7.1501                      sqlite3_column_text(session->own_identities_retrieve, 0);
  7.1502                  fpr = (const char *)
  7.1503                      sqlite3_column_text(session->own_identities_retrieve, 1);
  7.1504 -                user_id = PEP_OWN_USERID;
  7.1505 +                user_id = (const char *)
  7.1506 +                    sqlite3_column_text(session->own_identities_retrieve, 2);
  7.1507                  username = (const char *)
  7.1508 -                    sqlite3_column_text(session->own_identities_retrieve, 2);
  7.1509 +                    sqlite3_column_text(session->own_identities_retrieve, 3);
  7.1510                  comm_type = PEP_ct_pEp;
  7.1511                  lang = (const char *)
  7.1512 -                    sqlite3_column_text(session->own_identities_retrieve, 3);
  7.1513 +                    sqlite3_column_text(session->own_identities_retrieve, 4);
  7.1514                  flags = (unsigned int)
  7.1515 -                    sqlite3_column_int(session->own_identities_retrieve, 4);
  7.1516 +                    sqlite3_column_int(session->own_identities_retrieve, 5);
  7.1517  
  7.1518                  pEp_identity *ident = new_identity(address, fpr, user_id, username);
  7.1519                  if (!ident)
  7.1520 @@ -904,6 +1373,7 @@
  7.1521                      ident->lang[1] = lang[1];
  7.1522                      ident->lang[2] = 0;
  7.1523                  }
  7.1524 +                ident->me = true;
  7.1525                  ident->flags = flags;
  7.1526  
  7.1527                  _bl = identity_list_add(_bl, ident);
  7.1528 @@ -1036,24 +1506,50 @@
  7.1529            fpr && fpr[0]
  7.1530           ))
  7.1531          return PEP_ILLEGAL_VALUE;
  7.1532 -    
  7.1533 -    sqlite3_reset(session->set_own_key);
  7.1534 -    sqlite3_bind_text(session->set_own_key, 1, address, -1, SQLITE_STATIC);
  7.1535 -    sqlite3_bind_text(session->set_own_key, 2, fpr, -1, SQLITE_STATIC);
  7.1536 -
  7.1537 -    int result;
  7.1538 -    
  7.1539 -    result = sqlite3_step(session->set_own_key);
  7.1540 -    switch (result) {
  7.1541 -        case SQLITE_DONE:
  7.1542 -            status = PEP_STATUS_OK;
  7.1543 -            break;
  7.1544 -            
  7.1545 -        default:
  7.1546 -            status = PEP_UNKNOWN_ERROR;
  7.1547 +                        
  7.1548 +    // First see if we have it in own identities already, AND we retrieve
  7.1549 +    // our own user_id
  7.1550 +    char* my_user_id = NULL;
  7.1551 +    status = get_default_own_userid(session, &my_user_id);
  7.1552 +    if (status != PEP_STATUS_OK)
  7.1553 +        return status;
  7.1554 +        
  7.1555 +    if (!my_user_id) {
  7.1556 +        // We have no own user_id. So we cannot set it for an identity.
  7.1557 +        return PEP_CANNOT_FIND_IDENTITY;
  7.1558      }
  7.1559      
  7.1560 -    sqlite3_reset(session->set_own_key);
  7.1561 +    pEp_identity* my_id = NULL;
  7.1562 +    
  7.1563 +    status = get_identity(session, my_user_id, address, &my_id);
  7.1564 +
  7.1565 +    if (status == PEP_STATUS_OK && my_id) {
  7.1566 +        if (my_id->fpr && strcasecmp(my_id->fpr, fpr) == 0) {
  7.1567 +            // We're done. It was already here.
  7.1568 +            goto pep_free;
  7.1569 +        }           
  7.1570 +    }
  7.1571 +                
  7.1572 +    // If there's an id w/ user_id + address
  7.1573 +    if (my_id) {
  7.1574 +        free(my_id->fpr);
  7.1575 +        my_id->fpr = my_user_id;
  7.1576 +        my_id->comm_type = PEP_ct_pEp;
  7.1577 +        my_id->me = true;
  7.1578 +    }
  7.1579 +    else { // Else, we need a new identity
  7.1580 +        my_id = new_identity(address, fpr, my_user_id, NULL); 
  7.1581 +        if (status != PEP_STATUS_OK)
  7.1582 +            goto pep_free; 
  7.1583 +        my_id->me = true;
  7.1584 +        my_id->comm_type = PEP_ct_pEp;
  7.1585 +    }
  7.1586 +        
  7.1587 +    status = set_identity(session, my_id);
  7.1588 +    
  7.1589 +pep_free:
  7.1590 +    free(my_id);
  7.1591 +    free(my_user_id);
  7.1592      return status;
  7.1593  }
  7.1594  
     8.1 --- a/src/keymanagement.h	Mon Jan 15 12:26:14 2018 +0100
     8.2 +++ b/src/keymanagement.h	Mon Jan 29 12:15:51 2018 +0100
     8.3 @@ -14,39 +14,98 @@
     8.4  //  parameters:
     8.5  //      session (in)        session to use
     8.6  //      identity (inout)    identity information of communication partner
     8.7 -//                          (identity->fpr is OUT ONLY)
     8.8 +//                          (identity->fpr is OUT ONLY), and at least
     8.9 +//                          .address must be set. 
    8.10 +//                          If .username is set, it will be used to set or patch
    8.11 +//                          the username record for this identity.                         
    8.12  //  return value:
    8.13  //      PEP_STATUS_OK if identity could be updated,
    8.14 -//      PEP_GET_KEY_FAILED for own identity that must be completed (myself())
    8.15 +//      PEP_ILLEGAL_VALUE if called with illegal inputs, including an identity
    8.16 +//                        with .me set or with an own user_id specified in the
    8.17 +//                        *input* (see caveats) 
    8.18 +//      PEP_KEY_UNSUITABLE if a default key was found for this identity, no
    8.19 +//                         other acceptable keys were found; if this is returned,
    8.20 +//                         the reason for rejecting the first default key found
    8.21 +//                         may be found in the comm_type
    8.22  //      any other value on error
    8.23  //
    8.24  //  caveat:
    8.25 +//      at least identity->address must be a non-empty UTF-8 string as input
    8.26 +//      update_identity() never writes flags; use set_identity_flags() for
    8.27 +//      writing
    8.28 +//      this function NEVER reads the incoming fpr, only writes to it.
    8.29 +//      this function will fail if called on an identity which, with its input
    8.30 +//      values, *explicitly* indicates it is an own identity (i.e. .me is set
    8.31 +//      to true on input, or a user_id is given AND it is a known own user_id).
    8.32 +//      however, it can RETURN an own identity if this is not indicated a
    8.33 +//      priori, and in fact will do so with prejudice when not faced with a
    8.34 +//      matching default (i.e. it is forced to search by address only).
    8.35 +//      if the identity is known to be an own identity (or the caller wishes
    8.36 +//      to make it one), call myself() on the identity instead.
    8.37 +//
    8.38 +//      FIXME: is this next point accurate?
    8.39  //      if this function returns PEP_ct_unknown or PEP_ct_key_expired in
    8.40  //      identity->comm_type, the caller must insert the identity into the
    8.41  //      asynchronous management implementation, so retrieve_next_identity()
    8.42  //      will return this identity later
    8.43 -//      at least identity->address must be a non-empty UTF-8 string as input
    8.44 -//      update_identity() never writes flags; use set_identity_flags() for
    8.45 -//      writing
    8.46 -//      this function NEVER reads the incoming fpr, only writes to it.
    8.47 +//      END FIXME
    8.48  
    8.49  DYNAMIC_API PEP_STATUS update_identity(
    8.50          PEP_SESSION session, pEp_identity * identity
    8.51      );
    8.52  
    8.53 +// initialise_own_identities () - ensures that an own identity is complete
    8.54 +//
    8.55 +//  parameters:
    8.56 +//      session (in)        session to use
    8.57 +//      my_idents (inout)   identities of local user to quick-set
    8.58 +//                          For these, at least .address must be set.
    8.59 +//                          if no .user_id is set, AND the DB doesn't contain
    8.60 +//                          a default user_id, PEP_OWN_USERID will be used and
    8.61 +//                          become the perennial default for the DB.
    8.62 +//
    8.63 +//  return value:
    8.64 +//      PEP_STATUS_OK if identity could be set,
    8.65 +//      any other value on error
    8.66 +//
    8.67 +//  caveat:
    8.68 +//      this function does NOT generate keypairs. It is intended to
    8.69 +//      precede running of the engine on actual messages. It effectively
    8.70 +//      behaves like myself(), but when there would normally be key generation
    8.71 +//      (when there is no valid key, for example),
    8.72 +//      it instead stores an identity without keys.
    8.73 +//
    8.74 +//      N.B. to adapter devs - this function is likely unnecessary, so please
    8.75 +//      do not put work into exposing it yet. Tickets will be filed if need be.
    8.76  
    8.77 -// myself() - ensures that the own identity is being complete
    8.78 +DYNAMIC_API PEP_STATUS initialise_own_identities(PEP_SESSION session,
    8.79 +                                                 identity_list* my_idents);
    8.80 +
    8.81 +// myself() - ensures that an own identity is complete
    8.82  //
    8.83  //  parameters:
    8.84  //      session (in)        session to use
    8.85  //      identity (inout)    identity of local user
    8.86 -//                          at least .address, .username, .user_id must be set
    8.87 +//                          both .address and .user_id must be set.
    8.88 +//                          if .fpr is set, an attempt will be made to make
    8.89 +//                          that the default key for this identity after key
    8.90 +//                          validation
    8.91 +//                          if .fpr is not set, key retrieval is performed
    8.92 +//                          If .username is set, it will be used to set or patch
    8.93 +//                          the username record for this identity.                         
    8.94  //
    8.95  //  return value:
    8.96  //      PEP_STATUS_OK if identity could be completed or was already complete,
    8.97  //      any other value on error
    8.98 -//
    8.99  //  caveat:
   8.100 +//      If an fpr was entered and is not a valid key, the reason for failure
   8.101 +//      is immediately returned in the status and, possibly, identity->comm_type
   8.102 +//      If a default own user_id exists in the database, an alias will 
   8.103 +//      be created for the default for the input user_id. The ENGINE'S default
   8.104 +//      user_id is always returned in the .user_id field
   8.105 +//      myself() NEVER elects keys from the keyring; it will only choose keys
   8.106 +//      which have been set up explicitly via myself(), or which were imported
   8.107 +//      during a first time DB setup from an OpenPGP keyring (compatibility only) 
   8.108  //      this function generates a keypair on demand; because it's synchronous
   8.109  //      it can need a decent amount of time to return
   8.110  //      if you need to do this asynchronous, you need to return an identity
   8.111 @@ -130,6 +189,15 @@
   8.112  //  parameters:
   8.113  //      session (in)        session to use
   8.114  //      ident (in)          person and key which was compromised
   8.115 +//  caveat:
   8.116 +//      ident is INPUT ONLY. If you want updated trust on the identity, you'll have
   8.117 +//      to call update_identity or myself respectively after this.
   8.118 +//      N.B. If you are calling this on a key that is the identity or user default,
   8.119 +//      it will be removed as the default key for ANY identity and user for which
   8.120 +//      it is the default. Please keep in mind that the undo in undo_last_mistrust
   8.121 +//      will only undo the current identity's / it's user's default, not any
   8.122 +//      other identities which may be impacted (this will not affect most use
   8.123 +//      cases)
   8.124  
   8.125  DYNAMIC_API PEP_STATUS key_mistrusted(
   8.126          PEP_SESSION session,
   8.127 @@ -155,7 +223,7 @@
   8.128  DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session);
   8.129  
   8.130  
   8.131 -// trust_personal_key() - mark a key as trusted with a person
   8.132 +// trust_personal_key() - mark a key as trusted for a user
   8.133  //
   8.134  //  parameters:
   8.135  //      session (in)        session to use
   8.136 @@ -163,6 +231,11 @@
   8.137  //
   8.138  //  caveat:
   8.139  //      the fields user_id, address and fpr must be supplied
   8.140 +//      for non-own users, this will 1) set the trust bit on its comm type in the DN,
   8.141 +//      2) set this key as the identity default if the current identity default
   8.142 +//      is not trusted, and 3) set this key as the user default if the current
   8.143 +//      user default is not trusted.
   8.144 +//      For an own user, this is simply a call to myself().
   8.145  
   8.146  DYNAMIC_API PEP_STATUS trust_personal_key(
   8.147          PEP_SESSION session,
   8.148 @@ -170,12 +243,18 @@
   8.149      );
   8.150  
   8.151  
   8.152 -// key_reset_trust() - undo trust_personal_key and key_mistrusted() for keys
   8.153 -//                     we don't own
   8.154 -//
   8.155 +// key_reset_trust() - reset trust bit or explicitly mistrusted status for an identity and
   8.156 +//                     its accompanying key/user_id pair.
   8.157  //  parameters:
   8.158  //      session (in)        session to use
   8.159 -//      ident (in)          person and key which was compromized
   8.160 +//      ident (in)          identity for person and key whose trust status is to be reset
   8.161 +//
   8.162 +//  caveat:
   8.163 +//      ident is INPUT ONLY. If you want updated trust on the identity, you'll have
   8.164 +//      to call update_identity or myself respectively after this.
   8.165 +//      N.B. If you are calling this on a key that is the identity or user default,
   8.166 +//      it will be removed as the default key for the identity and user (but is still
   8.167 +//      available for key election, it is just not the cached default anymore)
   8.168  
   8.169  DYNAMIC_API PEP_STATUS key_reset_trust(
   8.170          PEP_SESSION session,
   8.171 @@ -263,6 +342,8 @@
   8.172         const char *fpr
   8.173      );
   8.174  
   8.175 +PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
   8.176 +
   8.177  #ifdef __cplusplus
   8.178  }
   8.179  #endif
     9.1 --- a/src/message_api.c	Mon Jan 15 12:26:14 2018 +0100
     9.2 +++ b/src/message_api.c	Mon Jan 29 12:15:51 2018 +0100
     9.3 @@ -920,6 +920,33 @@
     9.4      return NULL;    
     9.5  }
     9.6  
     9.7 +static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
     9.8 +                                             identity_list* list) {
     9.9 +
    9.10 +    PEP_STATUS status = PEP_STATUS_OK;
    9.11 +
    9.12 +    if (!session)
    9.13 +        return PEP_UNKNOWN_ERROR;
    9.14 +    
    9.15 +    identity_list* id_list_ptr = NULL;
    9.16 +        
    9.17 +    for (id_list_ptr = list; id_list_ptr; id_list_ptr = id_list_ptr->next) {
    9.18 +        pEp_identity* curr_identity = id_list_ptr->ident;
    9.19 +        if (curr_identity) {
    9.20 +            if (!is_me(session, curr_identity))
    9.21 +                status = update_identity(session, curr_identity);
    9.22 +            else
    9.23 +                status = myself(session, curr_identity);
    9.24 +        if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
    9.25 +            return status;
    9.26 +        }
    9.27 +        else
    9.28 +            break;
    9.29 +    }
    9.30 +    
    9.31 +    return PEP_STATUS_OK;                                  
    9.32 +}
    9.33 +
    9.34  static PEP_STATUS encrypt_PGP_MIME(
    9.35      PEP_SESSION session,
    9.36      const message *src,
    9.37 @@ -1206,13 +1233,17 @@
    9.38      return rating;
    9.39  }
    9.40  
    9.41 +// Internal function WARNING:
    9.42 +// Only call this on an ident that might have its FPR set from retrieval!
    9.43 +// (or on one without an fpr)
    9.44 +// We do not want myself() setting the fpr here.
    9.45  static PEP_comm_type _get_comm_type(
    9.46      PEP_SESSION session,
    9.47      PEP_comm_type max_comm_type,
    9.48      pEp_identity *ident
    9.49      )
    9.50  {
    9.51 -    PEP_STATUS status = update_identity(session, ident);
    9.52 +    PEP_STATUS status = PEP_STATUS_OK;
    9.53  
    9.54      if (max_comm_type == PEP_ct_compromized)
    9.55          return PEP_ct_compromized;
    9.56 @@ -1220,6 +1251,11 @@
    9.57      if (max_comm_type == PEP_ct_mistrusted)
    9.58          return PEP_ct_mistrusted;
    9.59  
    9.60 +    if (!is_me(session, ident))
    9.61 +        status = update_identity(session, ident);
    9.62 +    else
    9.63 +        status = myself(session, ident);
    9.64 +
    9.65      if (status == PEP_STATUS_OK) {
    9.66          if (ident->comm_type == PEP_ct_compromized)
    9.67              return PEP_ct_compromized;
    9.68 @@ -1433,6 +1469,15 @@
    9.69  
    9.70      *dst = NULL;
    9.71  
    9.72 +    if (src->from && (!src->from->user_id || src->from->user_id[0] == '\0')) {
    9.73 +        char* own_id = NULL;
    9.74 +        status = get_default_own_userid(session, &own_id);
    9.75 +        if (own_id) {
    9.76 +            free(src->from->user_id);
    9.77 +            src->from->user_id = own_id; // ownership transfer
    9.78 +        }
    9.79 +    }
    9.80 +    
    9.81      status = myself(session, src->from);
    9.82      if (status != PEP_STATUS_OK)
    9.83          GOTO(pep_error);
    9.84 @@ -1466,7 +1511,16 @@
    9.85              return PEP_ILLEGAL_VALUE;
    9.86          }
    9.87  
    9.88 -        PEP_STATUS _status = update_identity(session, _il->ident);
    9.89 +        PEP_STATUS _status = PEP_STATUS_OK;
    9.90 +        if (!is_me(session, _il->ident)) {
    9.91 +            _status = update_identity(session, _il->ident);
    9.92 +            if (_status == PEP_CANNOT_FIND_IDENTITY) {
    9.93 +                _il->ident->comm_type = PEP_ct_key_not_found;
    9.94 +                _status = PEP_STATUS_OK;
    9.95 +            }
    9.96 +        }
    9.97 +        else
    9.98 +            _status = myself(session, _il->ident);
    9.99          if (_status != PEP_STATUS_OK) {
   9.100              status = _status;
   9.101              GOTO(pep_error);
   9.102 @@ -1487,7 +1541,16 @@
   9.103      else
   9.104      {
   9.105          for (_il = src->to; _il && _il->ident; _il = _il->next) {
   9.106 -            PEP_STATUS _status = update_identity(session, _il->ident);
   9.107 +            PEP_STATUS _status = PEP_STATUS_OK;
   9.108 +            if (!is_me(session, _il->ident)) {
   9.109 +                _status = update_identity(session, _il->ident);
   9.110 +                if (_status == PEP_CANNOT_FIND_IDENTITY) {
   9.111 +                    _il->ident->comm_type = PEP_ct_key_not_found;
   9.112 +                    _status = PEP_STATUS_OK;
   9.113 +                }
   9.114 +            }
   9.115 +            else
   9.116 +                _status = myself(session, _il->ident);
   9.117              if (_status != PEP_STATUS_OK) {
   9.118                  status = _status;
   9.119                  GOTO(pep_error);
   9.120 @@ -1507,7 +1570,16 @@
   9.121          }
   9.122  
   9.123          for (_il = src->cc; _il && _il->ident; _il = _il->next) {
   9.124 -            PEP_STATUS _status = update_identity(session, _il->ident);
   9.125 +            PEP_STATUS _status = PEP_STATUS_OK;
   9.126 +            if (!is_me(session, _il->ident)) {
   9.127 +                _status = update_identity(session, _il->ident);
   9.128 +                if (_status == PEP_CANNOT_FIND_IDENTITY) {
   9.129 +                    _il->ident->comm_type = PEP_ct_key_not_found;
   9.130 +                    _status = PEP_STATUS_OK;
   9.131 +                }
   9.132 +            }
   9.133 +            else
   9.134 +                _status = myself(session, _il->ident);
   9.135              if (_status != PEP_STATUS_OK)
   9.136              {
   9.137                  status = _status;
   9.138 @@ -1659,18 +1731,26 @@
   9.139      if (src->enc_format != PEP_enc_none)
   9.140          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   9.141  
   9.142 +    if (target_id && (!target_id->user_id || target_id->user_id[0] == '\0')) {
   9.143 +        char* own_id = NULL;
   9.144 +        status = get_default_own_userid(session, &own_id);
   9.145 +        if (own_id) {
   9.146 +            free(target_id->user_id);
   9.147 +            target_id->user_id = own_id; // ownership transfer
   9.148 +        }
   9.149 +    }
   9.150 +
   9.151      status = myself(session, target_id);
   9.152      if (status != PEP_STATUS_OK)
   9.153          GOTO(pep_error);
   9.154  
   9.155      *dst = NULL;
   9.156  
   9.157 -
   9.158 -    PEP_STATUS _status = update_identity(session, target_id);
   9.159 -    if (_status != PEP_STATUS_OK) {
   9.160 -        status = _status;
   9.161 -        goto pep_error;
   9.162 -    }
   9.163 +    // PEP_STATUS _status = update_identity(session, target_id);
   9.164 +    // if (_status != PEP_STATUS_OK) {
   9.165 +    //     status = _status;
   9.166 +    //     goto pep_error;
   9.167 +    // }
   9.168  
   9.169      char* target_fpr = target_id->fpr;
   9.170      if (!target_fpr)
   9.171 @@ -1749,8 +1829,12 @@
   9.172      )
   9.173  {
   9.174      PEP_STATUS status;
   9.175 +
   9.176      if (src->from && src->from->address) {
   9.177 -        status = update_identity(session, src->from);
   9.178 +        if (!is_me(session, src->from))
   9.179 +            status = update_identity(session, src->from);
   9.180 +        else
   9.181 +            status = myself(session, src->from);
   9.182          if (status == PEP_STATUS_OK
   9.183                  && is_a_pEpmessage(src)
   9.184                  && src->from->comm_type >= PEP_ct_OpenPGP_unconfirmed
   9.185 @@ -1958,11 +2042,15 @@
   9.186                  return PEP_OUT_OF_MEMORY;
   9.187  
   9.188              status = get_trust(session, _sender);
   9.189 +            if (_sender->comm_type == PEP_ct_unknown) {
   9.190 +                get_key_rating(session, fpr, &_sender->comm_type);
   9.191 +            }
   9.192              if (_sender->comm_type != PEP_ct_unknown) {
   9.193                  *rating = keylist_rating(session, recipients, 
   9.194                              fpr, _rating(_sender->comm_type, 
   9.195                                            PEP_rating_undefined));
   9.196              }
   9.197 +            
   9.198              free_identity(_sender);
   9.199              if (status == PEP_CANNOT_FIND_IDENTITY)
   9.200                 status = PEP_STATUS_OK;
   9.201 @@ -2304,14 +2392,37 @@
   9.202          _private_il->ident->address)
   9.203          *imported_private = true;
   9.204  
   9.205 -    if (private_il && imported_private)
   9.206 +    if (private_il && imported_private) {
   9.207 +        // the private identity list should NOT be subject to myself() or
   9.208 +        // update_identity() at this point.
   9.209 +        // If the receiving app wants them to be in the trust DB, it
   9.210 +        // should call myself() on them upon return.
   9.211 +        // We do, however, prepare these so the app can use them
   9.212 +        // directly in a myself() call by putting the own_id on it.
   9.213 +        char* own_id = NULL;
   9.214 +        status = get_default_own_userid(session, &own_id);
   9.215 +        
   9.216 +        if (status != PEP_STATUS_OK) {
   9.217 +            free(own_id);
   9.218 +            own_id = NULL;
   9.219 +        }
   9.220 +        
   9.221 +        identity_list* il = _private_il;
   9.222 +        for ( ; il; il = il->next) {
   9.223 +            if (own_id) {
   9.224 +                free(il->ident->user_id);
   9.225 +                il->ident->user_id = strdup(own_id);
   9.226 +            }
   9.227 +            il->ident->me = true;
   9.228 +        }
   9.229          *private_il = _private_il;
   9.230 +        
   9.231 +        free(own_id);
   9.232 +    }
   9.233      else
   9.234          free_identity_list(_private_il);
   9.235 -
   9.236 -    if (imported_keys)
   9.237 -        status = _update_identity_for_incoming_message(session, src);
   9.238 -        
   9.239 + 
   9.240 +    
   9.241      return status;
   9.242  }
   9.243  
   9.244 @@ -2361,7 +2472,18 @@
   9.245      // Update src->from in case we just imported a key
   9.246      // we would need to check signature
   9.247      status = _update_identity_for_incoming_message(session, src);
   9.248 -    if(status != PEP_STATUS_OK)
   9.249 +    
   9.250 +    if (status == PEP_ILLEGAL_VALUE && src->from && is_me(session, src->from)) {
   9.251 +        // the above function should fail if it's us.
   9.252 +        // We don't need to update, as any revocations or expirations
   9.253 +        // of our own key imported above, which are all that we 
   9.254 +        // would care about for anything imported,
   9.255 +        // SHOULD get caught when they matter later.
   9.256 +        // (Private keys imported above are not stored in the trust DB)
   9.257 +        status = PEP_STATUS_OK;
   9.258 +    }
   9.259 +        
   9.260 +    if (status != PEP_STATUS_OK)
   9.261          return ADD_TO_LOG(status);
   9.262  
   9.263      /*** End Import any attached public keys and update identities accordingly ***/
   9.264 @@ -2522,8 +2644,12 @@
   9.265                                              // FIXME: free msg, but check references
   9.266                                              src = msg = inner_message;
   9.267                                              
   9.268 -                                            if (src->from)
   9.269 -                                                update_identity(session, src->from);
   9.270 +                                            if (src->from) {
   9.271 +                                                if (!is_me(session, src->from))
   9.272 +                                                    update_identity(session, (src->from));
   9.273 +                                                else
   9.274 +                                                    myself(session, src->from);
   9.275 +                                            }
   9.276                                              break;        
   9.277                                          }
   9.278                                          else { // should never happen
   9.279 @@ -2579,8 +2705,7 @@
   9.280      // 1. Check to see if this message is to us and contains an own key imported 
   9.281      // from own trusted message 
   9.282      if (msg && *rating >= PEP_rating_trusted && imported_private_key_address &&
   9.283 -        msg->to->ident->user_id &&
   9.284 -        strcmp(msg->to->ident->user_id, PEP_OWN_USERID) == 0) {
   9.285 +        msg->to && msg->to->ident && msg->to->ident->me) {
   9.286  
   9.287          // flag it as such
   9.288          *flags |= PEP_decrypt_flag_own_private_key;
   9.289 @@ -2682,8 +2807,12 @@
   9.290      for (il = identities; il != NULL; il = il->next)
   9.291      {
   9.292          if (il->ident)
   9.293 -        {
   9.294 -            PEP_STATUS status = update_identity(session, il->ident);
   9.295 +        {   
   9.296 +            PEP_STATUS status = PEP_STATUS_OK;
   9.297 +            if (!is_me(session, il->ident))
   9.298 +                status = update_identity(session, il->ident);
   9.299 +            else
   9.300 +                status = myself(session, il->ident);
   9.301              if (status == PEP_STATUS_OK)
   9.302              {
   9.303                  *max_comm_type = _get_comm_type(session, *max_comm_type,
   9.304 @@ -2749,7 +2878,7 @@
   9.305      if (!(session && ident && rating))
   9.306          return PEP_ILLEGAL_VALUE;
   9.307  
   9.308 -    if (_identity_me(ident))
   9.309 +    if (ident->me)
   9.310          status = _myself(session, ident, false, true);
   9.311      else
   9.312          status = update_identity(session, ident);
   9.313 @@ -3123,6 +3252,29 @@
   9.314      if (status != PEP_STATUS_OK)
   9.315          GOTO(pep_error);
   9.316  
   9.317 +    // MIME decode message delivers only addresses. We need more.
   9.318 +    if (tmp_msg->from) {
   9.319 +        if (!is_me(session, tmp_msg->from))
   9.320 +            status = update_identity(session, (tmp_msg->from));
   9.321 +        else
   9.322 +            status = myself(session, tmp_msg->from);
   9.323 +
   9.324 +        if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
   9.325 +            GOTO(pep_error);
   9.326 +    }
   9.327 +
   9.328 +    status = update_identity_recip_list(session, tmp_msg->to);
   9.329 +    if (status != PEP_STATUS_OK)
   9.330 +        GOTO(pep_error);
   9.331 +
   9.332 +    status = update_identity_recip_list(session, tmp_msg->cc);
   9.333 +    if (status != PEP_STATUS_OK)
   9.334 +        GOTO(pep_error);
   9.335 +
   9.336 +    status = update_identity_recip_list(session, tmp_msg->bcc);
   9.337 +    if (status != PEP_STATUS_OK)
   9.338 +        GOTO(pep_error);
   9.339 +
   9.340      PEP_STATUS decrypt_status = decrypt_message(session,
   9.341                                                  tmp_msg,
   9.342                                                  &dec_msg,
   9.343 @@ -3176,6 +3328,39 @@
   9.344      if (status != PEP_STATUS_OK)
   9.345          GOTO(pep_error);
   9.346  
   9.347 +    // MIME decode message delivers only addresses. We need more.
   9.348 +    if (tmp_msg->from) {
   9.349 +        char* own_id = NULL;
   9.350 +        status = get_default_own_userid(session, &own_id);
   9.351 +        free(tmp_msg->from->user_id);
   9.352 +        
   9.353 +        if (status != PEP_STATUS_OK || !own_id) {
   9.354 +            tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
   9.355 +        }
   9.356 +        else {
   9.357 +            tmp_msg->from->user_id = own_id; // ownership transfer
   9.358 +        }
   9.359 +            
   9.360 +        status = myself(session, tmp_msg->from);
   9.361 +        if (status != PEP_STATUS_OK)
   9.362 +            GOTO(pep_error);
   9.363 +    }
   9.364 +
   9.365 +    // Own identities can be retrieved here where they would otherwise
   9.366 +    // fail because we lack all other information. This is ok and even
   9.367 +    // desired. FIXME: IS it?
   9.368 +    status = update_identity_recip_list(session, tmp_msg->to);
   9.369 +    if (status != PEP_STATUS_OK)
   9.370 +        GOTO(pep_error);
   9.371 +
   9.372 +    status = update_identity_recip_list(session, tmp_msg->cc);
   9.373 +    if (status != PEP_STATUS_OK)
   9.374 +        GOTO(pep_error);
   9.375 +
   9.376 +    status = update_identity_recip_list(session, tmp_msg->bcc);
   9.377 +    if (status != PEP_STATUS_OK)
   9.378 +        GOTO(pep_error);
   9.379 +    
   9.380      // This isn't incoming, though... so we need to reverse the direction
   9.381      tmp_msg->dir = PEP_dir_outgoing;
   9.382      status = encrypt_message(session,
   9.383 @@ -3375,7 +3560,11 @@
   9.384      }
   9.385  got_keylist:
   9.386  
   9.387 -    status = update_identity(session, msg->from);
   9.388 +    if (!is_me(session, msg->from))
   9.389 +        status = update_identity(session, msg->from);
   9.390 +    else
   9.391 +        status = myself(session, msg->from);
   9.392 +
   9.393      if (status != PEP_STATUS_OK)
   9.394          GOTO(pep_error);
   9.395  
    10.1 --- a/src/pEpEngine.c	Mon Jan 15 12:26:14 2018 +0100
    10.2 +++ b/src/pEpEngine.c	Mon Jan 29 12:15:51 2018 +0100
    10.3 @@ -47,10 +47,10 @@
    10.4      "select id, word from wordlist where lang = lower(?1) "
    10.5      "and id = ?2 ;";
    10.6  
    10.7 -
    10.8  static const char *sql_get_identity =  
    10.9      "select fpr, username, comm_type, lang,"
   10.10 -    "   identity.flags | pgp_keypair.flags"
   10.11 +    "   identity.flags | pgp_keypair.flags,"
   10.12 +    "   is_own"
   10.13      "   from identity"
   10.14      "   join person on id = identity.user_id"
   10.15      "   join pgp_keypair on fpr = identity.main_key_id"
   10.16 @@ -63,10 +63,37 @@
   10.17      "          end) = 1"
   10.18      "   and identity.user_id = ?2;";
   10.19  
   10.20 +static const char *sql_get_identity_without_trust_check =  
   10.21 +    "select identity.main_key_id, username, lang,"
   10.22 +    "   identity.flags, is_own"
   10.23 +    "   from identity"
   10.24 +    "   join person on id = identity.user_id"
   10.25 +    "   where (case when (address = ?1) then (1)"
   10.26 +    "               when (lower(address) = lower(?1)) then (1)"
   10.27 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   10.28 +    "               else 0"
   10.29 +    "          end) = 1"
   10.30 +    "   and identity.user_id = ?2;";
   10.31 +
   10.32 +static const char *sql_get_identities_by_address =  
   10.33 +    "select user_id, identity.main_key_id, username, lang,"
   10.34 +    "   identity.flags, is_own"
   10.35 +    "   from identity"
   10.36 +    "   join person on id = identity.user_id"
   10.37 +    "   where (case when (address = ?1) then (1)"
   10.38 +    "               when (lower(address) = lower(?1)) then (1)"
   10.39 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   10.40 +    "               else 0"
   10.41 +    "          end) = 1;";
   10.42 +
   10.43  static const char *sql_replace_identities_fpr =  
   10.44      "update identity"
   10.45      "   set main_key_id = ?1 "
   10.46      "   where main_key_id = ?2 ;";
   10.47 +    
   10.48 +static const char *sql_remove_fpr_as_default =
   10.49 +    "update person set main_key_id = NULL where main_key_id = ?1 ;"
   10.50 +    "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   10.51  
   10.52  // Set person, but if already exist, only update.
   10.53  // if main_key_id already set, don't touch.
   10.54 @@ -79,11 +106,37 @@
   10.55  
   10.56  static const char *sql_set_device_group = 
   10.57      "update person set device_group = ?1 "
   10.58 -    "where id = '" PEP_OWN_USERID "';";
   10.59 +    "where id = ?2;";
   10.60 +
   10.61 +// This will cascade to identity and trust
   10.62 +static const char* sql_replace_userid =
   10.63 +    "update person set id = ?1 " 
   10.64 +    "where id = ?2;";
   10.65 +
   10.66 +static const char *sql_replace_main_user_fpr =  
   10.67 +    "update person "
   10.68 +    "   set main_key_id = ?1 "
   10.69 +    "   where id = ?2 ;";
   10.70 +
   10.71 +static const char *sql_get_main_user_fpr =  
   10.72 +    "select main_key_id from person"
   10.73 +    "   where id = ?1 ;";
   10.74 +
   10.75 +static const char *sql_refresh_userid_default_key =
   10.76 +    "update person "
   10.77 +    "   set main_key_id = "
   10.78 +    "       (select identity.main_key_id from identity "
   10.79 +    "           join trust on trust.user_id = identity.user_id "
   10.80 +    "               and trust.pgp_keypair_fpr = identity.main_key_id "
   10.81 +    "           join person on identity.user_id = identity.user_id "
   10.82 +    "       where identity.user_id = ?1 "
   10.83 +    "       order by trust.comm_type desc "
   10.84 +    "       limit 1) "
   10.85 +    "where id = ?1 ; ";
   10.86  
   10.87  static const char *sql_get_device_group = 
   10.88      "select device_group from person "
   10.89 -    "where id = '" PEP_OWN_USERID "';";
   10.90 +    "where id = ?1;";
   10.91  
   10.92  static const char *sql_set_pgp_keypair = 
   10.93      "insert or replace into pgp_keypair (fpr) "
   10.94 @@ -92,7 +145,7 @@
   10.95  static const char *sql_set_identity = 
   10.96      "insert or replace into identity ("
   10.97      " address, main_key_id, "
   10.98 -    " user_id, flags"
   10.99 +    " user_id, flags, is_own"
  10.100      ") values ("
  10.101      " ?1,"
  10.102      " upper(replace(?2,' ','')),"
  10.103 @@ -105,7 +158,8 @@
  10.104      // "    0)"
  10.105      // " ) | (?4 & 255)"
  10.106      /* set_identity ignores previous flags, and doesn't filter machine flags */
  10.107 -    " ?4"
  10.108 +    " ?4,"
  10.109 +    " ?5"
  10.110      ");";
  10.111          
  10.112  static const char *sql_set_identity_flags = 
  10.113 @@ -142,7 +196,7 @@
  10.114  static const char *sql_mark_as_compromized = 
  10.115      "update trust not indexed set comm_type = 15"
  10.116      " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
  10.117 -
  10.118 +    
  10.119  static const char *sql_crashdump = 
  10.120      "select timestamp, title, entity, description, comment"
  10.121      " from log order by timestamp desc limit ?1 ;";
  10.122 @@ -154,7 +208,6 @@
  10.123  static const char *sql_i18n_token = 
  10.124      "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
  10.125  
  10.126 -
  10.127  // blacklist
  10.128  static const char *sql_blacklist_add = 
  10.129      "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
  10.130 @@ -172,40 +225,39 @@
  10.131                  
  10.132  
  10.133  // Own keys
  10.134 +// We only care if it's 0 or non-zero
  10.135  static const char *sql_own_key_is_listed = 
  10.136      "select count(*) from ("
  10.137 -    " select main_key_id from person "
  10.138 -    "   where main_key_id = upper(replace(?1,' ',''))"
  10.139 -    "    and id = '" PEP_OWN_USERID "' "
  10.140 -    " union "
  10.141 -    "  select main_key_id from identity "
  10.142 -    "   where main_key_id = upper(replace(?1,' ',''))"
  10.143 -    "    and user_id = '" PEP_OWN_USERID "' "
  10.144 -    " union "
  10.145 -    "  select fpr from own_keys "
  10.146 -    "   where fpr = upper(replace(?1,' ',''))"
  10.147 -    " );";
  10.148 +    "   select pgp_keypair_fpr from trust"
  10.149 +    "      join identity on trust.user_id = identity.user_id"
  10.150 +    "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
  10.151 +    "           and identity.is_own = 1"
  10.152 +    ");";
  10.153  
  10.154  static const char *sql_own_identities_retrieve =  
  10.155 -    "select address, fpr, username, "
  10.156 +    "select address, fpr, username, identity.user_id, "
  10.157      "   lang, identity.flags | pgp_keypair.flags"
  10.158      "   from identity"
  10.159      "   join person on id = identity.user_id"
  10.160      "   join pgp_keypair on fpr = identity.main_key_id"
  10.161      "   join trust on id = trust.user_id"
  10.162      "       and pgp_keypair_fpr = identity.main_key_id"
  10.163 -    "   where identity.user_id = '" PEP_OWN_USERID "'"
  10.164 +    "   where identity.is_own = 1"
  10.165      "       and (identity.flags & ?1) = 0;";
  10.166 -        
  10.167 -static const char *sql_own_keys_retrieve =  
  10.168 -    "select fpr from own_keys"
  10.169 -    "   natural join identity"
  10.170 -    "   where (identity.flags & ?1) = 0;";
  10.171 -
  10.172 -static const char *sql_set_own_key = 
  10.173 -    "insert or replace into own_keys (address, user_id, fpr)"
  10.174 -    " values (?1, '" PEP_OWN_USERID "', upper(replace(?2,' ','')));";
  10.175 -
  10.176 +
  10.177 +static const char *sql_own_keys_retrieve = 
  10.178 +    "select pgp_keypair_fpr from trust"
  10.179 +    "   join identity on trust.user_id = identity.user_id"
  10.180 +    "   where identity.is_own = 1";
  10.181 +
  10.182 +static const char* sql_get_user_default_key =
  10.183 +    "select main_key_id from person" 
  10.184 +    "   where id = ?1;";
  10.185 +
  10.186 +static const char* sql_get_default_own_userid =
  10.187 +    "select id from person"
  10.188 +    "   join identity on id = identity.user_id"
  10.189 +    "   where identity.is_own = 1";
  10.190  
  10.191  // Sequence
  10.192  static const char *sql_sequence_value1 = 
  10.193 @@ -238,6 +290,14 @@
  10.194      "select revoked_fpr, revocation_date from revoked_keys"
  10.195      "    where replacement_fpr = upper(replace(?1,' ','')) ;";
  10.196  
  10.197 +static const char *sql_get_userid_alias_default =
  10.198 +    "select default_id from alternate_user_id "
  10.199 +    "   where alternate_id = ?1 ; ";
  10.200 +
  10.201 +static const char *sql_add_userid_alias =
  10.202 +    "insert or replace into alternate_user_id (default_id, alternate_id) "
  10.203 +    "values (?1, ?2) ;";
  10.204 +    
  10.205  static int user_version(void *_version, int count, char **text, char **name)
  10.206  {
  10.207      assert(_version);
  10.208 @@ -251,6 +311,56 @@
  10.209      return 0;
  10.210  }
  10.211  
  10.212 +static int table_contains_column(PEP_SESSION session, const char* table_name,
  10.213 +                                                      const char* col_name) {
  10.214 +
  10.215 +
  10.216 +    if (!session || !table_name || !col_name)
  10.217 +        return -1;
  10.218 +        
  10.219 +    // Table names can't be SQL parameters, so we do it this way.
  10.220 +    
  10.221 +    // these two must be the same number.
  10.222 +    char sql_buf[500];
  10.223 +    const size_t max_q_len = 500;
  10.224 +    
  10.225 +    size_t t_size, c_size, q_size;
  10.226 +    
  10.227 +    const char* q1 = "SELECT "; // 7
  10.228 +    const char* q2 = " from "; // 6
  10.229 +    const char* q3 = ";";       // 1
  10.230 +    
  10.231 +    q_size = 14;
  10.232 +    t_size = strlen(table_name);
  10.233 +    c_size = strlen(col_name);
  10.234 +    
  10.235 +    size_t query_len = q_size + c_size + t_size + 1;
  10.236 +    
  10.237 +    if (query_len > max_q_len)
  10.238 +        return -1;
  10.239 +
  10.240 +    strlcpy(sql_buf, q1, max_q_len);
  10.241 +    strlcat(sql_buf, col_name, max_q_len);
  10.242 +    strlcat(sql_buf, q2, max_q_len);
  10.243 +    strlcat(sql_buf, table_name, max_q_len);
  10.244 +    strlcat(sql_buf, q3, max_q_len);
  10.245 +
  10.246 +    sqlite3_stmt *stmt; 
  10.247 +
  10.248 +    sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
  10.249 +
  10.250 +    int retval = 0;
  10.251 +
  10.252 +    int rc = sqlite3_step(stmt);  
  10.253 +    if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
  10.254 +        retval = 1;
  10.255 +    }
  10.256 +
  10.257 +    sqlite3_finalize(stmt);      
  10.258 +        
  10.259 +    return retval;
  10.260 +}
  10.261 +
  10.262  DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
  10.263  {
  10.264      PEP_STATUS status = PEP_STATUS_OK;
  10.265 @@ -358,7 +468,7 @@
  10.266      sqlite3_busy_timeout(_session->system_db, 1000);
  10.267  
  10.268  // increment this when patching DDL
  10.269 -#define _DDL_USER_VERSION "5"
  10.270 +#define _DDL_USER_VERSION "6"
  10.271  
  10.272      if (in_first) {
  10.273  
  10.274 @@ -411,18 +521,19 @@
  10.275                  "   address text,\n"
  10.276                  "   user_id text\n"
  10.277                  "       references person (id)\n"
  10.278 -                "       on delete cascade,\n"
  10.279 +                "       on delete cascade on update cascade,\n"
  10.280                  "   main_key_id text\n"
  10.281                  "       references pgp_keypair (fpr)\n"
  10.282                  "       on delete set null,\n"
  10.283                  "   comment text,\n"
  10.284 -                "   flags integer default 0,"
  10.285 +                "   flags integer default 0,\n"
  10.286 +                "   is_own integer default 0,\n"
  10.287                  "   primary key (address, user_id)\n"
  10.288                  ");\n"
  10.289                  "create table if not exists trust (\n"
  10.290                  "   user_id text not null\n"
  10.291                  "       references person (id)\n"
  10.292 -                "       on delete cascade,\n"
  10.293 +                "       on delete cascade on update cascade,\n"
  10.294                  "   pgp_keypair_fpr text not null\n"
  10.295                  "       references pgp_keypair (fpr)\n"
  10.296                  "       on delete cascade,\n"
  10.297 @@ -447,18 +558,12 @@
  10.298                  "       on delete cascade,\n"
  10.299                  "   revocation_date integer\n"
  10.300                  ");\n"
  10.301 -                "create table if not exists own_keys (\n"
  10.302 -                "   address text,\n"
  10.303 -                "   user_id text,\n"
  10.304 -                "   fpr text not null\n"
  10.305 -                "       references pgp_keypair (fpr)\n"
  10.306 -                "       on delete cascade,\n"
  10.307 -                "   foreign key (address, user_id)\n"
  10.308 -                "       references identity\n"
  10.309 -                "       on delete cascade,\n"
  10.310 -                "   check (user_id = '" PEP_OWN_USERID "')\n"
  10.311 -                "   primary key (address, fpr)\n"
  10.312 -                ");\n" 
  10.313 +                // user id aliases
  10.314 +                "create table if not exists alternate_user_id (\n"
  10.315 +                "    default_id text references person (id)\n"
  10.316 +                "       on delete cascade on update cascade,\n"
  10.317 +                "    alternate_id text primary key\n"
  10.318 +                ");\n"
  10.319                  ,
  10.320              NULL,
  10.321              NULL,
  10.322 @@ -490,6 +595,48 @@
  10.323              NULL,
  10.324              NULL);
  10.325          assert(int_result == SQLITE_OK);
  10.326 +        
  10.327 +        // Sometimes the user_version wasn't set correctly. Check to see if this
  10.328 +        // is really necessary...
  10.329 +        if (version == 1) {
  10.330 +            bool version_changed = true;
  10.331 +            
  10.332 +            if (table_contains_column(_session, "identity", "is_own") > 0) {
  10.333 +                version = 6;
  10.334 +            }
  10.335 +            else if (table_contains_column(_session, "sequences", "own") > 0) {
  10.336 +                version = 3;
  10.337 +            }
  10.338 +            else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
  10.339 +                version = 2;
  10.340 +            }
  10.341 +            else {
  10.342 +                version_changed = false;
  10.343 +            }
  10.344 +            
  10.345 +            if (version_changed) {
  10.346 +                // set it in the DB, finally. Yeesh.
  10.347 +                char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
  10.348 +                sprintf(verbuf,"%d",version);
  10.349 +                
  10.350 +                size_t query_size = strlen(verbuf) + 25;
  10.351 +                char* query = calloc(query_size, 1);
  10.352 +                
  10.353 +                strlcpy(query, "pragma user_version = ", query_size);
  10.354 +                strlcat(query, verbuf, query_size);
  10.355 +                strlcat(query, ";", query_size);
  10.356 +                
  10.357 +                int_result = sqlite3_exec(
  10.358 +                    _session->db,
  10.359 +                    query,
  10.360 +                    user_version,
  10.361 +                    &version,
  10.362 +                    NULL
  10.363 +                );
  10.364 +                free(query);
  10.365 +            }
  10.366 +        }
  10.367 +
  10.368  
  10.369          if(version != 0) { 
  10.370              // Version has been already set
  10.371 @@ -510,7 +657,7 @@
  10.372              //     );
  10.373              //     assert(int_result == SQLITE_OK);
  10.374              // }
  10.375 -
  10.376 +            
  10.377              if (version < 2) {
  10.378                  int_result = sqlite3_exec(
  10.379                      _session->db,
  10.380 @@ -555,6 +702,81 @@
  10.381                  );
  10.382                  assert(int_result == SQLITE_OK);
  10.383              }
  10.384 +            
  10.385 +            if (version < 6) {
  10.386 +                int_result = sqlite3_exec(
  10.387 +                    _session->db,
  10.388 +                    "alter table identity\n"
  10.389 +                    "   add column is_own integer default 0;\n",
  10.390 +                    NULL,
  10.391 +                    NULL,
  10.392 +                    NULL
  10.393 +                );
  10.394 +                assert(int_result == SQLITE_OK);                
  10.395 +                int_result = sqlite3_exec(
  10.396 +                    _session->db,
  10.397 +                    "update identity\n"
  10.398 +                    "   set is_own = 1\n"
  10.399 +                    "   where (user_id = '" PEP_OWN_USERID "');\n",
  10.400 +                    NULL,
  10.401 +                    NULL,
  10.402 +                    NULL
  10.403 +                );
  10.404 +                assert(int_result == SQLITE_OK);    
  10.405 +
  10.406 +                // Turns out that just adding "on update cascade" in
  10.407 +                // sqlite is a PITA. We need to be able to cascade
  10.408 +                // person->id replacements (for temp ids like "TOFU_")
  10.409 +                // so here we go...
  10.410 +                int_result = sqlite3_exec(
  10.411 +                    _session->db,
  10.412 +                    "PRAGMA foreign_keys=off;\n"
  10.413 +                    "BEGIN TRANSACTION;\n"
  10.414 +                    "ALTER TABLE identity RENAME TO _identity_old;\n"
  10.415 +                    "create table identity (\n"
  10.416 +                    "   address text,\n"
  10.417 +                    "   user_id text\n"
  10.418 +                    "       references person (id)\n"
  10.419 +                    "       on delete cascade on update cascade,\n"
  10.420 +                    "   main_key_id text\n"
  10.421 +                    "       references pgp_keypair (fpr)\n"
  10.422 +                    "       on delete set null,\n"
  10.423 +                    "   comment text,\n"
  10.424 +                    "   flags integer default 0,\n"
  10.425 +                    "   is_own integer default 0,\n"
  10.426 +                    "   primary key (address, user_id)\n"
  10.427 +                    ");\n"
  10.428 +                    "INSERT INTO identity SELECT * FROM _identity_old;\n"
  10.429 +                    "DROP TABLE _identity_old;\n"
  10.430 +                    "ALTER TABLE trust RENAME TO _trust_old;\n"
  10.431 +                    "create table trust (\n"
  10.432 +                    "   user_id text not null\n"
  10.433 +                    "       references person (id)\n"
  10.434 +                    "       on delete cascade on update cascade,\n"
  10.435 +                    "   pgp_keypair_fpr text not null\n"
  10.436 +                    "       references pgp_keypair (fpr)\n"
  10.437 +                    "       on delete cascade,\n"
  10.438 +                    "   comm_type integer not null,\n"
  10.439 +                    "   comment text,\n"
  10.440 +                    "   primary key (user_id, pgp_keypair_fpr)\n"
  10.441 +                    ");\n"
  10.442 +                    "INSERT INTO trust SELECT * FROM _trust_old;\n"
  10.443 +                    "DROP TABLE _trust_old;\n"
  10.444 +                    "COMMIT;\n"
  10.445 +                    "\n"
  10.446 +                    "PRAGMA foreign_keys=on;\n"
  10.447 +                    "create table if not exists alternate_user_id (\n"
  10.448 +                    "    default_id text references person (id)\n"
  10.449 +                    "       on delete cascade on update cascade,\n"
  10.450 +                    "    alternate_id text primary key\n"
  10.451 +                    ");\n"
  10.452 +                    ,
  10.453 +                    NULL,
  10.454 +                    NULL,
  10.455 +                    NULL
  10.456 +                );
  10.457 +                assert(int_result == SQLITE_OK);    
  10.458 +            }
  10.459          }
  10.460          else { 
  10.461              // Version from DB was 0, it means this is initial setup.
  10.462 @@ -592,10 +814,57 @@
  10.463              (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  10.464      assert(int_result == SQLITE_OK);
  10.465  
  10.466 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  10.467 +            (int)strlen(sql_get_identity_without_trust_check), 
  10.468 +            &_session->get_identity_without_trust_check, NULL);
  10.469 +    assert(int_result == SQLITE_OK);
  10.470 +
  10.471 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  10.472 +            (int)strlen(sql_get_identities_by_address), 
  10.473 +            &_session->get_identities_by_address, NULL);
  10.474 +    assert(int_result == SQLITE_OK);
  10.475 +
  10.476 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  10.477 +            (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  10.478 +    assert(int_result == SQLITE_OK);
  10.479 +
  10.480 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  10.481 +            (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  10.482 +    assert(int_result == SQLITE_OK);
  10.483 +    
  10.484 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  10.485 +            (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  10.486 +    assert(int_result == SQLITE_OK);
  10.487 +
  10.488 +    int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  10.489 +            (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  10.490 +    assert(int_result == SQLITE_OK);
  10.491 +
  10.492 +    int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  10.493 +            (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  10.494 +    assert(int_result == SQLITE_OK);
  10.495 +
  10.496 +    int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  10.497 +            (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  10.498 +    assert(int_result == SQLITE_OK);
  10.499 +
  10.500 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  10.501 +            (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  10.502 +    assert(int_result == SQLITE_OK);
  10.503 +
  10.504 +    int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  10.505 +            (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  10.506 +    assert(int_result == SQLITE_OK);
  10.507 +
  10.508      int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  10.509              (int)strlen(sql_replace_identities_fpr), 
  10.510              &_session->replace_identities_fpr, NULL);
  10.511      assert(int_result == SQLITE_OK);
  10.512 +    
  10.513 +    int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  10.514 +            (int)strlen(sql_remove_fpr_as_default), 
  10.515 +            &_session->remove_fpr_as_default, NULL);
  10.516 +    assert(int_result == SQLITE_OK);
  10.517  
  10.518      int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  10.519              (int)strlen(sql_set_person), &_session->set_person, NULL);
  10.520 @@ -660,7 +929,7 @@
  10.521      int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  10.522              (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  10.523      assert(int_result == SQLITE_OK);
  10.524 -
  10.525 +    
  10.526      // blacklist
  10.527  
  10.528      int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  10.529 @@ -699,10 +968,10 @@
  10.530              &_session->own_keys_retrieve, NULL);
  10.531      assert(int_result == SQLITE_OK);
  10.532   
  10.533 -    int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  10.534 -            (int)strlen(sql_set_own_key),
  10.535 -            &_session->set_own_key, NULL);
  10.536 -    assert(int_result == SQLITE_OK);
  10.537 +    // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  10.538 +    //         (int)strlen(sql_set_own_key),
  10.539 +    //         &_session->set_own_key, NULL);
  10.540 +    // assert(int_result == SQLITE_OK);
  10.541   
  10.542      // Sequence
  10.543  
  10.544 @@ -745,9 +1014,6 @@
  10.545  
  10.546      // runtime config
  10.547  
  10.548 -#ifdef ANDROID
  10.549 -#elif TARGET_OS_IPHONE
  10.550 -#else /* Desktop */
  10.551      if (very_first)
  10.552      {
  10.553          // On first run, all private keys already present in PGP keyring 
  10.554 @@ -760,7 +1026,7 @@
  10.555          //
  10.556          // Indeed, if pEpEngine did import spoofed private keys in previous
  10.557          // install, then those keys become automatically trusted in case 
  10.558 -        // pEp_management.db is deleted.
  10.559 +        // management.db is deleted.
  10.560          //
  10.561          // A solution to distinguish bare GPG keyring from pEp keyring is
  10.562          // needed here. Then keys managed by pEpEngine wouldn't be
  10.563 @@ -784,7 +1050,6 @@
  10.564              }
  10.565          }
  10.566      }
  10.567 -#endif
  10.568  
  10.569      // sync_session set to own session by default
  10.570      // sync_session is then never null on a valid session
  10.571 @@ -833,8 +1098,22 @@
  10.572                  sqlite3_finalize(session->trustword);
  10.573              if (session->get_identity)
  10.574                  sqlite3_finalize(session->get_identity);
  10.575 +            if (session->get_identity_without_trust_check)
  10.576 +                sqlite3_finalize(session->get_identity_without_trust_check);
  10.577 +            if (session->get_identities_by_address)
  10.578 +                sqlite3_finalize(session->get_identities_by_address);            
  10.579 +            if (session->get_user_default_key)
  10.580 +                sqlite3_finalize(session->get_user_default_key);    
  10.581 +            if (session->get_default_own_userid)
  10.582 +                sqlite3_finalize(session->get_default_own_userid);
  10.583 +            if (session->get_userid_alias_default)
  10.584 +                sqlite3_finalize(session->get_userid_alias_default);
  10.585 +            if (session->add_userid_alias)
  10.586 +                sqlite3_finalize(session->add_userid_alias);
  10.587              if (session->replace_identities_fpr)
  10.588                  sqlite3_finalize(session->replace_identities_fpr);        
  10.589 +            if (session->remove_fpr_as_default)
  10.590 +                sqlite3_finalize(session->remove_fpr_as_default);            
  10.591              if (session->set_person)
  10.592                  sqlite3_finalize(session->set_person);
  10.593              if (session->set_device_group)
  10.594 @@ -865,6 +1144,14 @@
  10.595                  sqlite3_finalize(session->languagelist);
  10.596              if (session->i18n_token)
  10.597                  sqlite3_finalize(session->i18n_token);
  10.598 +            if (session->replace_userid)
  10.599 +                sqlite3_finalize(session->replace_userid);
  10.600 +            if (session->replace_main_user_fpr)
  10.601 +                sqlite3_finalize(session->replace_main_user_fpr);                
  10.602 +            if (session->get_main_user_fpr)
  10.603 +                sqlite3_finalize(session->get_main_user_fpr);
  10.604 +            if (session->refresh_userid_default_key)
  10.605 +                sqlite3_finalize(session->refresh_userid_default_key);
  10.606              if (session->blacklist_add)
  10.607                  sqlite3_finalize(session->blacklist_add);
  10.608              if (session->blacklist_delete)
  10.609 @@ -879,8 +1166,8 @@
  10.610                  sqlite3_finalize(session->own_identities_retrieve);
  10.611              if (session->own_keys_retrieve)
  10.612                  sqlite3_finalize(session->own_keys_retrieve);
  10.613 -            if (session->set_own_key)
  10.614 -                sqlite3_finalize(session->set_own_key);
  10.615 +            // if (session->set_own_key)
  10.616 +            //     sqlite3_finalize(session->set_own_key);
  10.617              if (session->sequence_value1)
  10.618                  sqlite3_finalize(session->sequence_value1);
  10.619              if (session->sequence_value2)
  10.620 @@ -1183,7 +1470,8 @@
  10.621      dup->lang[1] = src->lang[1];
  10.622      dup->lang[2] = 0;
  10.623      dup->flags = src->flags;
  10.624 -
  10.625 +    dup->me = src->me;
  10.626 +    
  10.627      return dup;
  10.628  }
  10.629  
  10.630 @@ -1198,6 +1486,124 @@
  10.631      }
  10.632  }
  10.633  
  10.634 +DYNAMIC_API PEP_STATUS get_default_own_userid(
  10.635 +        PEP_SESSION session, 
  10.636 +        char** userid
  10.637 +    )
  10.638 +{
  10.639 +    assert(session);
  10.640 +    assert(userid);
  10.641 +    
  10.642 +    if (!session || !userid)
  10.643 +        return PEP_ILLEGAL_VALUE;
  10.644 +        
  10.645 +    PEP_STATUS status = PEP_STATUS_OK;
  10.646 +    char* retval = NULL;
  10.647 +    
  10.648 +    sqlite3_reset(session->get_default_own_userid);
  10.649 +
  10.650 +    const int result = sqlite3_step(session->get_default_own_userid);
  10.651 +    const char* id;
  10.652 +    
  10.653 +    switch (result) {
  10.654 +        case SQLITE_ROW:
  10.655 +            id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  10.656 +            if (!id) {
  10.657 +                // Shouldn't happen.
  10.658 +                status = PEP_UNKNOWN_ERROR;
  10.659 +            }
  10.660 +            else {
  10.661 +                retval = strdup(id);
  10.662 +                if (!retval)
  10.663 +                    status = PEP_OUT_OF_MEMORY;
  10.664 +            }
  10.665 +            break;
  10.666 +        default:
  10.667 +            // Technically true, given how we find it, but FIXME we need a more descriptive error
  10.668 +            status = PEP_CANNOT_FIND_IDENTITY;
  10.669 +            *userid = NULL;
  10.670 +    }
  10.671 +
  10.672 +    *userid = retval;
  10.673 +
  10.674 +    sqlite3_reset(session->get_default_own_userid);
  10.675 +    
  10.676 +    return status;
  10.677 +}
  10.678 +
  10.679 +DYNAMIC_API PEP_STATUS get_userid_alias_default(
  10.680 +        PEP_SESSION session, 
  10.681 +        const char* alias_id,
  10.682 +        char** default_id) {
  10.683 +            
  10.684 +    assert(session);
  10.685 +    assert(alias_id);
  10.686 +    assert(alias_id[0]);
  10.687 +    assert(default_id);
  10.688 +
  10.689 +    if (!(session && alias_id && alias_id[0] && default_id))
  10.690 +        return PEP_ILLEGAL_VALUE;
  10.691 +
  10.692 +    PEP_STATUS status = PEP_STATUS_OK;
  10.693 +    char* retval = NULL;
  10.694 +
  10.695 +    sqlite3_reset(session->get_userid_alias_default);
  10.696 +    sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  10.697 +
  10.698 +    const char* tempid;
  10.699 +    
  10.700 +    const int result = sqlite3_step(session->get_userid_alias_default);
  10.701 +    switch (result) {
  10.702 +    case SQLITE_ROW:
  10.703 +        tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  10.704 +        if (tempid) {
  10.705 +            retval = strdup(tempid);
  10.706 +            assert(retval);
  10.707 +            if (retval == NULL)
  10.708 +                return PEP_OUT_OF_MEMORY;
  10.709 +        }
  10.710 +    
  10.711 +        *default_id = retval;
  10.712 +        break;
  10.713 +    default:
  10.714 +        status = PEP_CANNOT_FIND_ALIAS;
  10.715 +        *default_id = NULL;
  10.716 +    }
  10.717 +
  10.718 +    sqlite3_reset(session->get_userid_alias_default);
  10.719 +    return status;            
  10.720 +}
  10.721 +
  10.722 +DYNAMIC_API PEP_STATUS set_userid_alias (
  10.723 +        PEP_SESSION session, 
  10.724 +        const char* default_id,
  10.725 +        const char* alias_id) {
  10.726 +            
  10.727 +    int result;
  10.728 +
  10.729 +    assert(session);
  10.730 +    assert(default_id);
  10.731 +    assert(alias_id);
  10.732 +
  10.733 +    if (!(session && default_id && alias_id && 
  10.734 +          default_id[0] != '\0' && alias_id[0] != '\0'))
  10.735 +        return PEP_ILLEGAL_VALUE;
  10.736 +
  10.737 +    sqlite3_reset(session->add_userid_alias);
  10.738 +    sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  10.739 +            SQLITE_STATIC);
  10.740 +    sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  10.741 +            SQLITE_STATIC);
  10.742 +        
  10.743 +    result = sqlite3_step(session->add_userid_alias);
  10.744 +
  10.745 +    sqlite3_reset(session->add_userid_alias);
  10.746 +    if (result != SQLITE_DONE)
  10.747 +        return PEP_CANNOT_SET_ALIAS;
  10.748 +    
  10.749 +    return PEP_STATUS_OK;
  10.750 +}
  10.751 +
  10.752  DYNAMIC_API PEP_STATUS get_identity(
  10.753          PEP_SESSION session,
  10.754          const char *address,
  10.755 @@ -1249,6 +1655,9 @@
  10.756          }
  10.757          _identity->flags = (unsigned int)
  10.758              sqlite3_column_int(session->get_identity, 4);
  10.759 +        _identity->me = (unsigned int)
  10.760 +            sqlite3_column_int(session->get_identity, 5);
  10.761 +    
  10.762          *identity = _identity;
  10.763          break;
  10.764      default:
  10.765 @@ -1260,6 +1669,140 @@
  10.766      return status;
  10.767  }
  10.768  
  10.769 +PEP_STATUS get_identity_without_trust_check(
  10.770 +        PEP_SESSION session,
  10.771 +        const char *address,
  10.772 +        const char *user_id,
  10.773 +        pEp_identity **identity
  10.774 +    )
  10.775 +{
  10.776 +    PEP_STATUS status = PEP_STATUS_OK;
  10.777 +    static pEp_identity *_identity;
  10.778 +
  10.779 +    assert(session);
  10.780 +    assert(address);
  10.781 +    assert(address[0]);
  10.782 +    assert(identity);
  10.783 +
  10.784 +    if (!(session && address && address[0] && identity))
  10.785 +        return PEP_ILLEGAL_VALUE;
  10.786 +
  10.787 +    *identity = NULL;
  10.788 +
  10.789 +    sqlite3_reset(session->get_identity_without_trust_check);
  10.790 +    sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  10.791 +    sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  10.792 +
  10.793 +    const int result = sqlite3_step(session->get_identity_without_trust_check);
  10.794 +    switch (result) {
  10.795 +    case SQLITE_ROW:
  10.796 +        _identity = new_identity(
  10.797 +                address,
  10.798 +                (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  10.799 +                user_id,
  10.800 +                (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  10.801 +                );
  10.802 +        assert(_identity);
  10.803 +        if (_identity == NULL)
  10.804 +            return PEP_OUT_OF_MEMORY;
  10.805 +
  10.806 +        _identity->comm_type = PEP_ct_unknown;
  10.807 +        const char* const _lang = (const char *)
  10.808 +            sqlite3_column_text(session->get_identity_without_trust_check, 2);
  10.809 +        if (_lang && _lang[0]) {
  10.810 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  10.811 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  10.812 +            assert(_lang[2] == 0);
  10.813 +            _identity->lang[0] = _lang[0];
  10.814 +            _identity->lang[1] = _lang[1];
  10.815 +            _identity->lang[2] = 0;
  10.816 +        }
  10.817 +        _identity->flags = (unsigned int)
  10.818 +            sqlite3_column_int(session->get_identity_without_trust_check, 3);
  10.819 +        _identity->me = (unsigned int)
  10.820 +            sqlite3_column_int(session->get_identity_without_trust_check, 4);
  10.821 +    
  10.822 +        *identity = _identity;
  10.823 +        break;
  10.824 +    default:
  10.825 +        status = PEP_CANNOT_FIND_IDENTITY;
  10.826 +        *identity = NULL;
  10.827 +    }
  10.828 +
  10.829 +    sqlite3_reset(session->get_identity_without_trust_check);
  10.830 +    return status;
  10.831 +}
  10.832 +
  10.833 +PEP_STATUS get_identities_by_address(
  10.834 +        PEP_SESSION session,
  10.835 +        const char *address,
  10.836 +        identity_list** id_list
  10.837 +    )
  10.838 +{
  10.839 +    pEp_identity* ident;
  10.840 +
  10.841 +    assert(session);
  10.842 +    assert(address);
  10.843 +    assert(address[0]);
  10.844 +    assert(id_list);
  10.845 +
  10.846 +    if (!(session && address && address[0] && id_list))
  10.847 +        return PEP_ILLEGAL_VALUE;
  10.848 +
  10.849 +    *id_list = NULL;
  10.850 +    identity_list* ident_list = NULL;
  10.851 +
  10.852 +    sqlite3_reset(session->get_identities_by_address);
  10.853 +    sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  10.854 +    int result;
  10.855 +
  10.856 +    while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  10.857 +        //"select user_id, main_key_id, username, comm_type, lang,"
  10.858 +        //"   identity.flags, is_own"
  10.859 +        ident = new_identity(
  10.860 +                address,
  10.861 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  10.862 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  10.863 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  10.864 +                );
  10.865 +        assert(ident);
  10.866 +        if (ident == NULL)
  10.867 +            return PEP_OUT_OF_MEMORY;
  10.868 +
  10.869 +        ident->comm_type = PEP_ct_unknown;
  10.870 +        
  10.871 +        const char* const _lang = (const char *)
  10.872 +            sqlite3_column_text(session->get_identities_by_address, 3);
  10.873 +        if (_lang && _lang[0]) {
  10.874 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  10.875 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  10.876 +            assert(_lang[2] == 0);
  10.877 +            ident->lang[0] = _lang[0];
  10.878 +            ident->lang[1] = _lang[1];
  10.879 +            ident->lang[2] = 0;
  10.880 +        }
  10.881 +        ident->flags = (unsigned int)
  10.882 +            sqlite3_column_int(session->get_identities_by_address, 4);
  10.883 +        ident->me = (unsigned int)
  10.884 +            sqlite3_column_int(session->get_identities_by_address, 5);
  10.885 +    
  10.886 +        if (ident_list)
  10.887 +            identity_list_add(ident_list, ident);
  10.888 +        else
  10.889 +            ident_list = new_identity_list(ident);
  10.890 +    }
  10.891 +
  10.892 +    sqlite3_reset(session->get_identities_by_address);
  10.893 +    
  10.894 +    *id_list = ident_list;
  10.895 +    
  10.896 +    if (!ident_list)
  10.897 +        return PEP_CANNOT_FIND_IDENTITY;
  10.898 +    
  10.899 +    return PEP_STATUS_OK;
  10.900 +}
  10.901 +
  10.902 +
  10.903  DYNAMIC_API PEP_STATUS set_identity(
  10.904          PEP_SESSION session, const pEp_identity *identity
  10.905      )
  10.906 @@ -1283,7 +1826,7 @@
  10.907      bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
  10.908      
  10.909      if (has_fpr) {    
  10.910 -        // blacklist check
  10.911 +        // blacklist check - FIXME: ENGINE-294 will remove
  10.912          status = blacklist_is_listed(session, identity->fpr, &listed);
  10.913          assert(status == PEP_STATUS_OK);
  10.914          if (status != PEP_STATUS_OK)
  10.915 @@ -1340,6 +1883,7 @@
  10.916      sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
  10.917              SQLITE_STATIC);
  10.918      sqlite3_bind_int(session->set_identity, 4, identity->flags);
  10.919 +    sqlite3_bind_int(session->set_identity, 5, identity->me);
  10.920      result = sqlite3_step(session->set_identity);
  10.921      sqlite3_reset(session->set_identity);
  10.922      if (result != SQLITE_DONE) {
  10.923 @@ -1348,22 +1892,6 @@
  10.924      }
  10.925  
  10.926      if (has_fpr) {
  10.927 -        if(strcmp(identity->user_id, PEP_OWN_USERID) == 0) {
  10.928 -            sqlite3_reset(session->set_own_key);
  10.929 -            sqlite3_bind_text(session->set_own_key, 1, identity->address, -1,
  10.930 -                SQLITE_STATIC);
  10.931 -            sqlite3_bind_text(session->set_own_key, 2, identity->fpr, -1,
  10.932 -                SQLITE_STATIC);
  10.933 -            result = sqlite3_step(session->set_own_key);
  10.934 -            sqlite3_reset(session->set_own_key);
  10.935 -            if (result != SQLITE_DONE) {
  10.936 -                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  10.937 -                return PEP_CANNOT_SET_PGP_KEYPAIR;
  10.938 -            }
  10.939 -        }
  10.940 -
  10.941 -        // status = set_trust(session, identity->user_id, identity->fpr,
  10.942 -        //                    identity->comm_type)
  10.943          sqlite3_reset(session->set_trust);
  10.944          sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
  10.945                  SQLITE_STATIC);
  10.946 @@ -1385,6 +1913,28 @@
  10.947          return PEP_COMMIT_FAILED;
  10.948  }
  10.949  
  10.950 +PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  10.951 +                                 const char* fpr) 
  10.952 +{
  10.953 +    assert(fpr);
  10.954 +    
  10.955 +    if (!session || !fpr)
  10.956 +        return PEP_ILLEGAL_VALUE;
  10.957 +            
  10.958 +    sqlite3_reset(session->remove_fpr_as_default);
  10.959 +    sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  10.960 +                      SQLITE_STATIC);
  10.961 +
  10.962 +    int result = sqlite3_step(session->remove_fpr_as_default);
  10.963 +    sqlite3_reset(session->remove_fpr_as_default);
  10.964 +    
  10.965 +    if (result != SQLITE_DONE)
  10.966 +        return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  10.967 +
  10.968 +    return PEP_STATUS_OK;
  10.969 +}
  10.970 +
  10.971 +
  10.972  PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  10.973                                   const char* old_fpr, 
  10.974                                   const char* new_fpr) 
  10.975 @@ -1410,7 +1960,6 @@
  10.976      return PEP_STATUS_OK;
  10.977  }
  10.978  
  10.979 -
  10.980  PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  10.981                                  const char* fpr, 
  10.982                                  PEP_comm_type comm_type)
  10.983 @@ -1443,6 +1992,15 @@
  10.984      if (!(session && group_name))
  10.985          return PEP_ILLEGAL_VALUE;
  10.986  
  10.987 +    // 1. Get own user_id
  10.988 +    char* user_id = NULL;
  10.989 +    PEP_STATUS status = get_default_own_userid(session, &user_id);
  10.990 +    
  10.991 +    // No user_id is returned in this case, no need to free;
  10.992 +    if (status != PEP_STATUS_OK)
  10.993 +        return status;
  10.994 +        
  10.995 +    // 2. Set device group
  10.996      sqlite3_reset(session->set_device_group);
  10.997      if(group_name){
  10.998          sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  10.999 @@ -1450,9 +2008,15 @@
 10.1000      } else {
 10.1001          sqlite3_bind_null(session->set_device_group, 1);
 10.1002      }
 10.1003 +    
 10.1004 +    sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
 10.1005 +            SQLITE_STATIC);
 10.1006  
 10.1007      result = sqlite3_step(session->set_device_group);
 10.1008      sqlite3_reset(session->set_device_group);
 10.1009 +    
 10.1010 +    free(user_id);
 10.1011 +    
 10.1012      if (result != SQLITE_DONE)
 10.1013          return PEP_CANNOT_SET_PERSON;
 10.1014  
 10.1015 @@ -1470,7 +2034,18 @@
 10.1016      if (!(session && group_name))
 10.1017          return PEP_ILLEGAL_VALUE;
 10.1018  
 10.1019 +    // 1. Get own user_id
 10.1020 +    char* user_id = NULL;
 10.1021 +    status = get_default_own_userid(session, &user_id);
 10.1022 +    
 10.1023 +    // No user_id is returned in this case, no need to free;
 10.1024 +    if (status != PEP_STATUS_OK)
 10.1025 +        return status;
 10.1026 +
 10.1027 +    // 2. get device group
 10.1028      sqlite3_reset(session->get_device_group);
 10.1029 +    sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
 10.1030 +            SQLITE_STATIC);
 10.1031  
 10.1032      result = sqlite3_step(session->get_device_group);
 10.1033      switch (result) {
 10.1034 @@ -1488,6 +2063,7 @@
 10.1035          status = PEP_RECORD_NOT_FOUND;
 10.1036      }
 10.1037  
 10.1038 +    free(user_id);
 10.1039      sqlite3_reset(session->get_device_group);
 10.1040      return status;
 10.1041  }
 10.1042 @@ -1513,8 +2089,10 @@
 10.1043      sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
 10.1044              SQLITE_STATIC);
 10.1045      sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
 10.1046 -            SQLITE_STATIC);
 10.1047 +        SQLITE_STATIC);
 10.1048 +        
 10.1049      result = sqlite3_step(session->set_identity_flags);
 10.1050 +
 10.1051      sqlite3_reset(session->set_identity_flags);
 10.1052      if (result != SQLITE_DONE)
 10.1053          return PEP_CANNOT_SET_IDENTITY;
 10.1054 @@ -1549,11 +2127,120 @@
 10.1055      sqlite3_reset(session->unset_identity_flags);
 10.1056      if (result != SQLITE_DONE)
 10.1057          return PEP_CANNOT_SET_IDENTITY;
 10.1058 -
 10.1059 -    identity->flags &= ~flags;
 10.1060 +        identity->flags &= ~flags;
 10.1061 +
 10.1062      return PEP_STATUS_OK;
 10.1063  }
 10.1064  
 10.1065 +
 10.1066 +PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
 10.1067 +                              const char* new_uid) {
 10.1068 +    assert(session);
 10.1069 +    assert(old_uid);
 10.1070 +    assert(new_uid);
 10.1071 +    
 10.1072 +    if (!session || !old_uid || !new_uid)
 10.1073 +        return PEP_ILLEGAL_VALUE;
 10.1074 +
 10.1075 +
 10.1076 +    int result;
 10.1077 +
 10.1078 +    sqlite3_reset(session->replace_userid);
 10.1079 +    sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
 10.1080 +            SQLITE_STATIC);
 10.1081 +    sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
 10.1082 +            SQLITE_STATIC);
 10.1083 +    result = sqlite3_step(session->replace_userid);
 10.1084 +    sqlite3_reset(session->replace_userid);
 10.1085 +    if (result != SQLITE_DONE)
 10.1086 +        return PEP_CANNOT_SET_PERSON; // May need clearer retval
 10.1087 +
 10.1088 +    return PEP_STATUS_OK;
 10.1089 +}
 10.1090 +
 10.1091 +PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
 10.1092 +    assert(session);
 10.1093 +    assert(user_id);
 10.1094 +    
 10.1095 +    if (!session || !user_id)
 10.1096 +        return PEP_ILLEGAL_VALUE;
 10.1097 +
 10.1098 +    int result;
 10.1099 +
 10.1100 +    sqlite3_reset(session->refresh_userid_default_key);
 10.1101 +    sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
 10.1102 +            SQLITE_STATIC);
 10.1103 +    result = sqlite3_step(session->refresh_userid_default_key);
 10.1104 +    sqlite3_reset(session->refresh_userid_default_key);
 10.1105 +    if (result != SQLITE_DONE)
 10.1106 +        return PEP_CANNOT_SET_PERSON;
 10.1107 +
 10.1108 +    return PEP_STATUS_OK;    
 10.1109 +}
 10.1110 +
 10.1111 +PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
 10.1112 +                                 const char* new_fpr) {
 10.1113 +    assert(session);
 10.1114 +    assert(user_id);
 10.1115 +    assert(new_fpr);
 10.1116 +    
 10.1117 +    if (!session || !user_id || !new_fpr)
 10.1118 +        return PEP_ILLEGAL_VALUE;
 10.1119 +
 10.1120 +    int result;
 10.1121 +
 10.1122 +    sqlite3_reset(session->replace_main_user_fpr);
 10.1123 +    sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
 10.1124 +            SQLITE_STATIC);
 10.1125 +    sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
 10.1126 +            SQLITE_STATIC);
 10.1127 +    result = sqlite3_step(session->replace_main_user_fpr);
 10.1128 +    sqlite3_reset(session->replace_main_user_fpr);
 10.1129 +    if (result != SQLITE_DONE)
 10.1130 +        return PEP_CANNOT_SET_PERSON;
 10.1131 +
 10.1132 +    return PEP_STATUS_OK;
 10.1133 +}
 10.1134 +
 10.1135 +PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
 10.1136 +                             const char* user_id,
 10.1137 +                             char** main_fpr)
 10.1138 +{
 10.1139 +    PEP_STATUS status = PEP_STATUS_OK;
 10.1140 +    int result;
 10.1141 +    
 10.1142 +    assert(session);
 10.1143 +    assert(user_id);
 10.1144 +    assert(main_fpr);
 10.1145 +    
 10.1146 +    if (!(session && user_id && user_id[0] && main_fpr))
 10.1147 +        return PEP_ILLEGAL_VALUE;
 10.1148 +        
 10.1149 +    *main_fpr = NULL;
 10.1150 +    
 10.1151 +    sqlite3_reset(session->get_main_user_fpr);
 10.1152 +    sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
 10.1153 +                      SQLITE_STATIC);
 10.1154 +    result = sqlite3_step(session->get_main_user_fpr);
 10.1155 +    switch (result) {
 10.1156 +    case SQLITE_ROW: {
 10.1157 +        const char* _fpr = 
 10.1158 +            (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
 10.1159 +        if (_fpr)
 10.1160 +            *main_fpr = strdup(_fpr);
 10.1161 +        if (!(*main_fpr))
 10.1162 +            status = PEP_OUT_OF_MEMORY;
 10.1163 +        break;
 10.1164 +    }
 10.1165 +    default:
 10.1166 +        status = PEP_CANNOT_FIND_PERSON;
 10.1167 +    }
 10.1168 +
 10.1169 +    sqlite3_reset(session->get_main_user_fpr);
 10.1170 +    return status;
 10.1171 +}
 10.1172 +
 10.1173 +
 10.1174  DYNAMIC_API PEP_STATUS mark_as_compromized(
 10.1175          PEP_SESSION session,
 10.1176          const char *fpr
 10.1177 @@ -1584,17 +2271,49 @@
 10.1178      free(p);
 10.1179  }
 10.1180  
 10.1181 +PEP_STATUS set_trust(PEP_SESSION session, 
 10.1182 +                     const char* user_id,
 10.1183 +                     const char* fpr, 
 10.1184 +                     PEP_comm_type comm_type) 
 10.1185 +{
 10.1186 +    assert(session);
 10.1187 +    assert(user_id);
 10.1188 +    assert(fpr);
 10.1189 +    
 10.1190 +    if (!session || !user_id || user_id[0] == '\0' || !fpr || fpr[0] == '\0')
 10.1191 +        return PEP_ILLEGAL_VALUE;
 10.1192 +        
 10.1193 +    int result;
 10.1194 +                
 10.1195 +    sqlite3_reset(session->set_trust);
 10.1196 +    sqlite3_bind_text(session->set_trust, 1, user_id, -1,
 10.1197 +            SQLITE_STATIC);
 10.1198 +    sqlite3_bind_text(session->set_trust, 2, fpr, -1,
 10.1199 +            SQLITE_STATIC);
 10.1200 +    sqlite3_bind_int(session->set_trust, 3, comm_type);
 10.1201 +    result = sqlite3_step(session->set_trust);
 10.1202 +    assert(result == SQLITE_DONE);
 10.1203 +    sqlite3_reset(session->set_trust);
 10.1204 +    if (result != SQLITE_DONE)
 10.1205 +        return PEP_CANNOT_SET_TRUST;
 10.1206 +
 10.1207 +    return PEP_STATUS_OK;
 10.1208 +}
 10.1209 +
 10.1210 +
 10.1211  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
 10.1212  {
 10.1213      PEP_STATUS status = PEP_STATUS_OK;
 10.1214      int result;
 10.1215  
 10.1216 -    assert(session);
 10.1217 -    assert(identity);
 10.1218 -    assert(identity->user_id);
 10.1219 -    assert(identity->user_id[0]);
 10.1220 -    assert(identity->fpr);
 10.1221 -    assert(identity->fpr[0]);
 10.1222 +    // We need to be able to test that we break correctly without shutting
 10.1223 +    // asserts off everywhere.
 10.1224 +    // assert(session);
 10.1225 +    // assert(identity);
 10.1226 +    // assert(identity->user_id);
 10.1227 +    // assert(identity->user_id[0]);
 10.1228 +    // assert(identity->fpr);
 10.1229 +    // assert(identity->fpr[0]);
 10.1230  
 10.1231      if (!(session && identity && identity->user_id && identity->user_id[0] &&
 10.1232                  identity->fpr && identity->fpr[0]))
    11.1 --- a/src/pEpEngine.h	Mon Jan 15 12:26:14 2018 +0100
    11.2 +++ b/src/pEpEngine.h	Mon Jan 29 12:15:51 2018 +0100
    11.3 @@ -37,6 +37,9 @@
    11.4      PEP_INIT_GPGME_INIT_FAILED                      = 0x0111,
    11.5      PEP_INIT_NO_GPG_HOME                            = 0x0112,
    11.6      PEP_INIT_NETPGP_INIT_FAILED                     = 0x0113,
    11.7 +    PEP_INIT_CANNOT_DETERMINE_GPG_VERSION           = 0x0114,
    11.8 +    PEP_INIT_UNSUPPORTED_GPG_VERSION                = 0x0115,
    11.9 +    PEP_INIT_CANNOT_CONFIG_GPG_AGENT                = 0x0116,
   11.10  
   11.11      PEP_INIT_SQLITE3_WITHOUT_MUTEX                  = 0x0120,
   11.12      PEP_INIT_CANNOT_OPEN_DB                         = 0x0121,
   11.13 @@ -47,6 +50,7 @@
   11.14      PEP_GET_KEY_FAILED                              = 0x0203,
   11.15      PEP_CANNOT_EXPORT_KEY                           = 0x0204,
   11.16      PEP_CANNOT_EDIT_KEY                             = 0x0205,
   11.17 +    PEP_KEY_UNSUITABLE                              = 0x0206,
   11.18      
   11.19      PEP_CANNOT_FIND_IDENTITY                        = 0x0301,
   11.20      PEP_CANNOT_SET_PERSON                           = 0x0381,
   11.21 @@ -54,6 +58,10 @@
   11.22      PEP_CANNOT_SET_IDENTITY                         = 0x0383,
   11.23      PEP_CANNOT_SET_TRUST                            = 0x0384,
   11.24      PEP_KEY_BLACKLISTED                             = 0x0385,
   11.25 +    PEP_CANNOT_FIND_PERSON                          = 0x0386,
   11.26 +    
   11.27 +    PEP_CANNOT_FIND_ALIAS                           = 0x0391,
   11.28 +    PEP_CANNOT_SET_ALIAS                            = 0x0392,
   11.29      
   11.30      PEP_UNENCRYPTED                                 = 0x0400,
   11.31      PEP_VERIFIED                                    = 0x0401,
   11.32 @@ -470,7 +478,6 @@
   11.33      // the first octet flags are app defined settings
   11.34      PEP_idf_not_for_sync = 0x0001,   // don't use this identity for sync
   11.35      PEP_idf_list = 0x0002,           // identity of list of persons
   11.36 -
   11.37      // the second octet flags are calculated
   11.38      PEP_idf_devicegroup = 0x0100     // identity of a device group member
   11.39  } identity_flags;
   11.40 @@ -486,13 +493,15 @@
   11.41      char *address;              // C string with address UTF-8 encoded
   11.42      char *fpr;                  // C string with fingerprint UTF-8 encoded
   11.43      char *user_id;              // C string with user ID UTF-8 encoded
   11.44 -                                // user_id must be set to "pEp_own_userId"
   11.45 +                                // user_id MIGHT be set to "pEp_own_userId"
   11.46                                  // (use PEP_OWN_USERID preprocessor define)
   11.47                                  // if this is own user's identity.
   11.48 +                                // But it is not REQUIRED to be.
   11.49      char *username;             // C string with user name UTF-8 encoded
   11.50      PEP_comm_type comm_type;    // type of communication with this ID
   11.51      char lang[3];               // language of conversation
   11.52                                  // ISO 639-1 ALPHA-2, last byte is 0
   11.53 +    bool me;                    // if this is the local user herself/himself
   11.54      identity_flags_t flags;     // identity_flag1 | identity_flag2 | ...
   11.55  } pEp_identity;
   11.56  
   11.57 @@ -600,6 +609,67 @@
   11.58          PEP_SESSION session, const pEp_identity *identity
   11.59      );
   11.60  
   11.61 +// get_default own_userid() - get the user_id of the own user
   11.62 +//
   11.63 +//    parameters:
   11.64 +//        session (in)        session handle
   11.65 +//        userid  (out)       own user id (if it exists)
   11.66 +//
   11.67 +//    return value:
   11.68 +//        PEP_STATUS_OK = 0             userid was found
   11.69 +//        PEP_CANNOT_FIND_IDENTITY      no own_user found in the DB
   11.70 +//        PEP_UNKNOWN_ERROR             results were returned, but no ID
   11.71 +//                                      found (no reason this should ever occur)
   11.72 +//    caveat:
   11.73 +//        userid will be NULL if not found; otherwise, returned string
   11.74 +//        belongs to the caller.
   11.75 +
   11.76 +DYNAMIC_API PEP_STATUS get_default_own_userid(
   11.77 +        PEP_SESSION session, 
   11.78 +        char** userid
   11.79 +    );
   11.80 +
   11.81 +// get_userid_alias_default() - get the default user_id which corresponds
   11.82 +//                              to an alias
   11.83 +//    parameters:
   11.84 +//        session (in)        session handle
   11.85 +//        alias_id (in)       the user_id which may be an alias for a default id
   11.86 +//        default_id (out)    the default id for this alias, if the alias
   11.87 +//                            is in the DB as an alias, else NULL
   11.88 +//    return value:
   11.89 +//        PEP_STATUS_OK = 0             userid was found
   11.90 +//        PEP_CANNOT_FIND_ALIAS         this userid is not listed as an 
   11.91 +//                                      alias in the DB
   11.92 +//        PEP_UNKNOWN_ERROR             results were returned, but no ID
   11.93 +//                                      found (no reason this should ever occur)
   11.94 +//    caveat:
   11.95 +//        default_id will be NULL if not found; otherwise, returned string
   11.96 +//        belongs to the caller.
   11.97 +//        also, current implementation does NOT check to see if this userid
   11.98 +//        IS a default.
   11.99 +
  11.100 +DYNAMIC_API PEP_STATUS get_userid_alias_default(
  11.101 +        PEP_SESSION session, 
  11.102 +        const char* alias_id,
  11.103 +        char** default_id);
  11.104 +
  11.105 +// set_userid_alias() - set an alias to correspond to a default id
  11.106 +//    parameters:
  11.107 +//        session (in)        session handle
  11.108 +//        default_id (in)     the default id for this alias. This must
  11.109 +//                            correspond to the default user_id for an
  11.110 +//                            entry in the person (user) table.
  11.111 +//        alias_id (in)       the alias to be set for this default id
  11.112 +//    return value:
  11.113 +//        PEP_STATUS_OK = 0             userid was found
  11.114 +//        PEP_CANNOT_SET_ALIAS          there was an error setting this
  11.115 +
  11.116 +DYNAMIC_API PEP_STATUS set_userid_alias (
  11.117 +        PEP_SESSION session, 
  11.118 +        const char* default_id,
  11.119 +        const char* alias_id);
  11.120 +
  11.121 +
  11.122  // set_device_group() - update own person's device group
  11.123  //
  11.124  //    parameters:
  11.125 @@ -853,7 +923,7 @@
  11.126  //  parameters:
  11.127  //      session (in)            session handle
  11.128  //      identity (inout)        user_id and fpr to check as UTF-8 strings (in)
  11.129 -//                              user_id and comm_type as result (out)
  11.130 +//                              comm_type as result (out)
  11.131  //
  11.132  //  this function modifies the given identity struct; the struct remains in
  11.133  //  the ownership of the caller
  11.134 @@ -1127,6 +1197,38 @@
  11.135  
  11.136  DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session);
  11.137  
  11.138 +// This is used internally when there is a temporary identity to be retrieved
  11.139 +// that may not yet have an FPR attached. See get_identity() for functionality,
  11.140 +// params and caveats.
  11.141 +PEP_STATUS get_identity_without_trust_check(
  11.142 +        PEP_SESSION session,
  11.143 +        const char *address,
  11.144 +        const char *user_id,
  11.145 +        pEp_identity **identity
  11.146 +    );
  11.147 +    
  11.148 +PEP_STATUS get_identities_by_address(
  11.149 +        PEP_SESSION session,
  11.150 +        const char *address,
  11.151 +        identity_list** id_list
  11.152 +    );
  11.153 +        
  11.154 +PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  11.155 +                              const char* new_uid);
  11.156 +                              
  11.157 +PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  11.158 +                                    const char* fpr);
  11.159 +                              
  11.160 +                                    
  11.161 +PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  11.162 +                             const char* user_id,
  11.163 +                             char** main_fpr);
  11.164 +
  11.165 +PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  11.166 +                              const char* new_fpr);
  11.167 +    
  11.168 +PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id);
  11.169 +
  11.170  #ifdef __cplusplus
  11.171  }
  11.172  #endif
    12.1 --- a/src/pEp_internal.h	Mon Jan 15 12:26:14 2018 +0100
    12.2 +++ b/src/pEp_internal.h	Mon Jan 29 12:15:51 2018 +0100
    12.3 @@ -82,7 +82,6 @@
    12.4  #include "sqlite3.h"
    12.5  #endif
    12.6  
    12.7 -#define _EXPORT_PEP_ENGINE_DLL
    12.8  #include "pEpEngine.h"
    12.9  
   12.10  // If not specified, build for GPG
   12.11 @@ -124,7 +123,13 @@
   12.12      sqlite3_stmt *log;
   12.13      sqlite3_stmt *trustword;
   12.14      sqlite3_stmt *get_identity;
   12.15 +    sqlite3_stmt *get_identity_without_trust_check;
   12.16 +    sqlite3_stmt *get_identities_by_address;
   12.17      sqlite3_stmt *replace_identities_fpr;
   12.18 +    sqlite3_stmt *replace_main_user_fpr;
   12.19 +    sqlite3_stmt *get_main_user_fpr;
   12.20 +    sqlite3_stmt *refresh_userid_default_key;
   12.21 +    sqlite3_stmt *remove_fpr_as_default;
   12.22      sqlite3_stmt *set_person;
   12.23      sqlite3_stmt *set_device_group;
   12.24      sqlite3_stmt *get_device_group;
   12.25 @@ -141,6 +146,7 @@
   12.26      sqlite3_stmt *crashdump;
   12.27      sqlite3_stmt *languagelist;
   12.28      sqlite3_stmt *i18n_token;
   12.29 +    sqlite3_stmt *replace_userid;
   12.30  
   12.31      // blacklist
   12.32      sqlite3_stmt *blacklist_add;
   12.33 @@ -152,7 +158,11 @@
   12.34      sqlite3_stmt *own_key_is_listed;
   12.35      sqlite3_stmt *own_identities_retrieve;
   12.36      sqlite3_stmt *own_keys_retrieve;
   12.37 -    sqlite3_stmt *set_own_key;
   12.38 +    sqlite3_stmt *get_user_default_key;
   12.39 +        
   12.40 +    sqlite3_stmt *get_default_own_userid;
   12.41 +
   12.42 +//    sqlite3_stmt *set_own_key;
   12.43  
   12.44      // sequence value
   12.45      sqlite3_stmt *sequence_value1;
   12.46 @@ -163,6 +173,10 @@
   12.47      sqlite3_stmt *set_revoked;
   12.48      sqlite3_stmt *get_revoked;
   12.49  
   12.50 +    // aliases
   12.51 +    sqlite3_stmt *get_userid_alias_default;
   12.52 +    sqlite3_stmt *add_userid_alias;
   12.53 +
   12.54      // callbacks
   12.55      examine_identity_t examine_identity;
   12.56      void *examine_management;
   12.57 @@ -340,13 +354,6 @@
   12.58      return comparison == 0;
   12.59  }
   12.60  
   12.61 -static inline bool _identity_me(
   12.62 -        pEp_identity * identity
   12.63 -    )
   12.64 -{
   12.65 -    return identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0;
   12.66 -}
   12.67 -
   12.68  // size is the length of the bytestr that's coming in. This is really only intended
   12.69  // for comparing two full strings. If charstr's length is different from bytestr_size,
   12.70  // we'll return a non-zero value.
   12.71 @@ -369,6 +376,32 @@
   12.72  #endif
   12.73  }
   12.74  
   12.75 +static inline bool is_me(PEP_SESSION session, pEp_identity* test_ident) {
   12.76 +    bool retval = false;
   12.77 +    if (test_ident && test_ident->user_id) {
   12.78 +        char* def_id = NULL;
   12.79 +        get_default_own_userid(session, &def_id);
   12.80 +        if (test_ident->me || 
   12.81 +            (def_id && strcmp(def_id, test_ident->user_id) == 0)) {
   12.82 +            retval = true;
   12.83 +        }
   12.84 +        free(def_id);
   12.85 +    }
   12.86 +    return retval;
   12.87 +}
   12.88 +
   12.89 +#ifndef EMPTYSTR
   12.90 +#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
   12.91 +#endif
   12.92 +
   12.93 +#ifndef _MIN
   12.94 +#define _MIN(A, B) ((B) > (A) ? (A) : (B))
   12.95 +#endif
   12.96 +#ifndef _MAX
   12.97 +#define _MAX(A, B) ((B) > (A) ? (B) : (A))
   12.98 +#endif
   12.99 +
  12.100 +
  12.101  // These are globals used in generating message IDs and should only be
  12.102  // computed once, as they're either really constants or OS-dependent
  12.103  
    13.1 --- a/src/pEp_string.c	Mon Jan 15 12:26:14 2018 +0100
    13.2 +++ b/src/pEp_string.c	Mon Jan 29 12:15:51 2018 +0100
    13.3 @@ -1,6 +1,7 @@
    13.4  // This file is under GNU General Public License 3.0
    13.5  // see LICENSE.txt
    13.6  
    13.7 +#include "platform.h"
    13.8  #include "pEp_string.h"
    13.9  
   13.10  #include <stdlib.h>
   13.11 @@ -8,10 +9,6 @@
   13.12  
   13.13  DYNAMIC_API char * new_string(const char *src, size_t len)
   13.14  {
   13.15 -    assert(src || len);
   13.16 -    if (!(src || len))
   13.17 -        return NULL;
   13.18 -
   13.19      char *s = NULL;
   13.20      if (src) {
   13.21          if (len)
   13.22 @@ -21,7 +18,7 @@
   13.23          assert(s);
   13.24      }
   13.25      else {
   13.26 -        s = calloc(1, len);
   13.27 +        s = calloc(1, len + 1);
   13.28          assert(s);
   13.29      }
   13.30  
    14.1 --- a/src/pEp_string.h	Mon Jan 15 12:26:14 2018 +0100
    14.2 +++ b/src/pEp_string.h	Mon Jan 29 12:15:51 2018 +0100
    14.3 @@ -20,12 +20,9 @@
    14.4  //  return value:
    14.5  //      pointer to string object or NULL if out of memory
    14.6  //
    14.7 -//  caveat:
    14.8 -//      one of the two parameters has to be set at least
    14.9 -//
   14.10  //  calling with str and len is equivalent to strndup()
   14.11  //  calling with str but len=0 is equivalent to strdup()
   14.12 -//  calling with str=NULL and len is equivalent to calloc()
   14.13 +//  calling with str=NULL is equivalent to calloc()
   14.14  
   14.15  DYNAMIC_API char * new_string(const char *src, size_t len);
   14.16  
    15.1 --- a/src/pgp_gpg.c	Mon Jan 15 12:26:14 2018 +0100
    15.2 +++ b/src/pgp_gpg.c	Mon Jan 29 12:15:51 2018 +0100
    15.3 @@ -174,6 +174,55 @@
    15.4      return false;
    15.5  }
    15.6  
    15.7 +static PEP_STATUS _version_test(const char *s)
    15.8 +{
    15.9 +    char *_s = strdup(s);
   15.10 +    if (!_s)
   15.11 +        return PEP_OUT_OF_MEMORY;
   15.12 +
   15.13 +    int major;
   15.14 +    int minor;
   15.15 +    int revision;
   15.16 +
   15.17 +    char *lasts = NULL;
   15.18 +    char *p = strtok_r(_s, ".", &lasts);
   15.19 +    if (!p)
   15.20 +        goto unsupported;
   15.21 +    else
   15.22 +        major = atoi(p);
   15.23 +
   15.24 +    p = strtok_r(NULL, ".", &lasts);
   15.25 +    if (!p)
   15.26 +        goto unsupported;
   15.27 +    else
   15.28 +        minor = atoi(p);
   15.29 +
   15.30 +    p = strtok_r(NULL, ".", &lasts);
   15.31 +    if (!p)
   15.32 +        goto unsupported;
   15.33 +    else
   15.34 +        revision = atoi(p);
   15.35 +
   15.36 +    free(_s);
   15.37 +    _s = NULL;
   15.38 +
   15.39 +    if (major > 2)
   15.40 +        return PEP_STATUS_OK;
   15.41 +
   15.42 +    if (major == 2 && minor > 1)
   15.43 +        return PEP_STATUS_OK;
   15.44 +
   15.45 +    if (major == 2 && minor == 0 && revision == 30)
   15.46 +        return PEP_STATUS_OK;
   15.47 +
   15.48 +    if (major == 2 && minor == 1 && revision >= 17)
   15.49 +        return PEP_STATUS_OK;
   15.50 +
   15.51 +unsupported:
   15.52 +    free(_s);
   15.53 +    return PEP_INIT_UNSUPPORTED_GPG_VERSION;
   15.54 +}
   15.55 +
   15.56  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
   15.57  {
   15.58      PEP_STATUS status = PEP_STATUS_OK;
   15.59 @@ -202,13 +251,16 @@
   15.60          stringlist_add(conf_keys, "ignore-time-conflict");
   15.61          stringlist_add(conf_values, "");
   15.62  
   15.63 +        stringlist_add(conf_keys, "allow-freeform-uid");
   15.64 +        stringlist_add(conf_values, "");
   15.65 +
   15.66          bResult = ensure_config_values(conf_keys, conf_values, gpg_conf());
   15.67  
   15.68          free_stringlist(conf_keys);
   15.69          free_stringlist(conf_values);
   15.70  
   15.71          assert(bResult);
   15.72 -        if(!bResult){
   15.73 +        if (!bResult) {
   15.74              status = PEP_INIT_NO_GPG_HOME;
   15.75              goto pep_error;
   15.76          }
   15.77 @@ -225,8 +277,8 @@
   15.78          free_stringlist(conf_values);
   15.79  
   15.80          assert(bResult);
   15.81 -        if(!bResult){
   15.82 -            status = PEP_INIT_NO_GPG_HOME; /* FIXME: Wrong error here? */
   15.83 +        if (!bResult) {
   15.84 +            status = PEP_INIT_CANNOT_CONFIG_GPG_AGENT;
   15.85              goto pep_error;
   15.86          }
   15.87  
   15.88 @@ -238,6 +290,25 @@
   15.89  
   15.90          memset(&gpg, 0, sizeof(struct gpg_s));
   15.91  
   15.92 +        gpg.gpgme_get_engine_info
   15.93 +            = (gpgme_get_engine_info_t) (intptr_t) dlsym(gpgme,
   15.94 +            "gpgme_get_engine_info");
   15.95 +        assert(gpg.gpgme_get_engine_info);
   15.96 +
   15.97 +        gpgme_engine_info_t info;
   15.98 +        int err = gpg.gpgme_get_engine_info(&info);
   15.99 +        assert(err == GPG_ERR_NO_ERROR);
  15.100 +        if (err != GPG_ERR_NO_ERROR)
  15.101 +            return PEP_OUT_OF_MEMORY;
  15.102 +
  15.103 +        assert(info->version);
  15.104 +        if (!info->version)
  15.105 +            return PEP_INIT_CANNOT_DETERMINE_GPG_VERSION;
  15.106 +
  15.107 +        status = _version_test(info->version);
  15.108 +        if (status != PEP_STATUS_OK)
  15.109 +            return status;
  15.110 +
  15.111          gpg.gpgme_set_locale
  15.112              = (gpgme_set_locale_t) (intptr_t) dlsym(gpgme,
  15.113              "gpgme_set_locale");
  15.114 @@ -256,11 +327,6 @@
  15.115              = (gpgme_release_t) (intptr_t) dlsym(gpgme, "gpgme_release");
  15.116          assert(gpg.gpgme_release);
  15.117  
  15.118 -        gpg.gpgme_get_engine_info
  15.119 -            = (gpgme_get_engine_info_t) (intptr_t) dlsym(gpgme,
  15.120 -            "gpgme_get_engine_info");
  15.121 -        assert(gpg.gpgme_get_engine_info);
  15.122 -
  15.123          gpg.gpgme_set_protocol
  15.124              = (gpgme_set_protocol_t) (intptr_t) dlsym(gpgme,
  15.125              "gpgme_set_protocol");
    16.1 --- a/src/pgp_gpg.h	Mon Jan 15 12:26:14 2018 +0100
    16.2 +++ b/src/pgp_gpg.h	Mon Jan 29 12:15:51 2018 +0100
    16.3 @@ -42,7 +42,7 @@
    16.4      );
    16.5  
    16.6  PEP_STATUS pgp_list_keyinfo(
    16.7 -    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
    16.8 +        PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
    16.9      );
   16.10  
   16.11  PEP_STATUS pgp_generate_keypair(
    17.1 --- a/src/platform_windows.h	Mon Jan 15 12:26:14 2018 +0100
    17.2 +++ b/src/platform_windows.h	Mon Jan 29 12:15:51 2018 +0100
    17.3 @@ -5,15 +5,16 @@
    17.4  
    17.5  // Windows platform specifica
    17.6  
    17.7 +#define _EXPORT_PEP_ENGINE_DLL
    17.8  #pragma warning(disable : 4996)
    17.9  
   17.10 -// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
   17.11 -// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
   17.12 -// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
   17.13 -// Including winsock2.h here fixes the problem for now...
   17.14 -#ifdef WIN32 
   17.15 -#include <winsock2.h>
   17.16 -#endif // WIN32 
   17.17 +// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
   17.18 +// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
   17.19 +// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
   17.20 +// Including winsock2.h here fixes the problem for now...
   17.21 +#ifdef WIN32 
   17.22 +#include <winsock2.h>
   17.23 +#endif // WIN32 
   17.24  
   17.25  #include <Rpc.h>
   17.26  #include <string.h>
   17.27 @@ -85,7 +86,7 @@
   17.28  int uuid_parse(char *in, pEpUUID uu);
   17.29  void uuid_unparse_upper(pEpUUID uu, uuid_string_t out);
   17.30  
   17.31 -#ifndef inline
   17.32 +#ifndef __cplusplus
   17.33  #define inline __inline
   17.34  #endif
   17.35  
    18.1 --- a/src/sync_actions.c	Mon Jan 15 12:26:14 2018 +0100
    18.2 +++ b/src/sync_actions.c	Mon Jan 29 12:15:51 2018 +0100
    18.3 @@ -56,8 +56,14 @@
    18.4      // key created first wins
    18.5  
    18.6      Identity me = NULL;
    18.7 -    PEP_STATUS status = get_identity(session, partner->address, PEP_OWN_USERID,
    18.8 -            &me);
    18.9 +    
   18.10 +    char* own_id = NULL;
   18.11 +    PEP_STATUS status = get_default_own_userid(session, &own_id);
   18.12 +    if (own_id) {
   18.13 +        status = get_identity(session, partner->address, own_id,
   18.14 +                              &me);
   18.15 +        free(own_id);
   18.16 +    }
   18.17      if (status == PEP_OUT_OF_MEMORY)
   18.18          return invalid_out_of_memory;
   18.19      if (status != PEP_STATUS_OK)
   18.20 @@ -142,9 +148,15 @@
   18.21      if (!session->notifyHandshake)
   18.22          return PEP_SYNC_NO_NOTIFY_CALLBACK;
   18.23  
   18.24 +    char* own_id = NULL;
   18.25 +    status = get_default_own_userid(session, &own_id);
   18.26 +        
   18.27      // notifyHandshake take ownership of given identities
   18.28      pEp_identity *me = NULL;
   18.29 -    status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
   18.30 +    if (own_id) {
   18.31 +        status = get_identity(session, partner->address, own_id, &me);
   18.32 +        free(own_id);
   18.33 +    }
   18.34      if (status != PEP_STATUS_OK)
   18.35          goto error;
   18.36      
   18.37 @@ -235,16 +247,23 @@
   18.38      )
   18.39  {
   18.40      PEP_STATUS status = PEP_STATUS_OK;
   18.41 -
   18.42 +    
   18.43 +    char* own_id = NULL;
   18.44 +    status = get_default_own_userid(session, &own_id);
   18.45 +    
   18.46 +    // FIXME: Is this where and what we wanna do with this?
   18.47 +    if (status != PEP_STATUS_OK)
   18.48 +        return status;
   18.49 +        
   18.50      for (identity_list *il = group_keys; il && il->ident; il = il->next) {
   18.51  
   18.52 -        if (strcmp(il->ident->user_id, PEP_OWN_USERID)!=0) {
   18.53 +        if (strcmp(il->ident->user_id, own_id)!=0) {
   18.54              assert(0);
   18.55              continue;
   18.56          }
   18.57          // Check that identity isn't excluded from sync.
   18.58          pEp_identity *stored_identity = NULL;
   18.59 -        status = get_identity(session, il->ident->address, PEP_OWN_USERID,
   18.60 +        status = get_identity(session, il->ident->address, own_id,
   18.61                  &stored_identity);
   18.62          if (status == PEP_STATUS_OK) {
   18.63              if(stored_identity->flags & PEP_idf_not_for_sync){
   18.64 @@ -258,7 +277,8 @@
   18.65          if (status != PEP_STATUS_OK)
   18.66              break;
   18.67      }
   18.68 -
   18.69 +    
   18.70 +    free(own_id);
   18.71      return status;
   18.72  }
   18.73      
    19.1 --- a/src/sync_impl.c	Mon Jan 15 12:26:14 2018 +0100
    19.2 +++ b/src/sync_impl.c	Mon Jan 29 12:15:51 2018 +0100
    19.3 @@ -71,6 +71,7 @@
    19.4      assert(session && sync_msg);
    19.5      if (!(session && sync_msg))
    19.6          return PEP_ILLEGAL_VALUE;
    19.7 +    char* own_id = NULL;
    19.8  
    19.9      bool msgIsFromGroup = false;
   19.10      if(sync_msg->is_a_message){
   19.11 @@ -275,16 +276,24 @@
   19.12      // partner identity must be explicitely added DB to later
   19.13      // be able to communicate securely with it.
   19.14      if(partner){
   19.15 +        
   19.16 +        status = get_default_own_userid(session, &own_id);
   19.17 +        
   19.18 +        if (!own_id)
   19.19 +            own_id = strdup(PEP_OWN_USERID);
   19.20 +            
   19.21          // protect virtual user IDs 
   19.22          if((strncmp("TOFU_", partner->user_id, 6) == 0 &&
   19.23             strlen(partner->user_id) == strlen(partner->address) + 6 &&
   19.24             strcmp(partner->user_id + 6, partner->address)) ||
   19.25          // protect own ID 
   19.26 -           (strcmp(PEP_OWN_USERID, partner->user_id) == 0)){
   19.27 +           (strcmp(own_id, partner->user_id) == 0)){
   19.28              status = PEP_SYNC_ILLEGAL_MESSAGE;
   19.29 +            free(own_id);
   19.30              goto error;
   19.31          }
   19.32  
   19.33 +        free(own_id);
   19.34          // partner IDs are UUIDs bound to session lifespan
   19.35          // and therefore partner identities are not supposed
   19.36          // to mutate over time, but just not be used anymore.
   19.37 @@ -349,7 +358,8 @@
   19.38      }
   19.39  
   19.40      free(sync_msg);
   19.41 -
   19.42 +    free(own_id);
   19.43 +    
   19.44      return status;
   19.45  }
   19.46  
   19.47 @@ -426,6 +436,9 @@
   19.48      bool discard = false;
   19.49      bool force_keep_msg = false;
   19.50  
   19.51 +    char* own_id = NULL;
   19.52 +    PEP_STATUS own_id_status = get_default_own_userid(session, &own_id);
   19.53 +
   19.54      for (bloblist_t *bl = src->attachments; bl && bl->value; bl = bl->next) {
   19.55          if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sync") == 0
   19.56                  && bl->size) {
   19.57 @@ -451,11 +464,18 @@
   19.58                              msg->header.me.address->size);
   19.59  
   19.60                  if(null_terminated_address){
   19.61 -                    status = get_identity(session, 
   19.62 -                                          null_terminated_address, 
   19.63 -                                          PEP_OWN_USERID, 
   19.64 -                                          &check_me);
   19.65 -                    free(null_terminated_address);
   19.66 +                    
   19.67 +                    if (own_id) {                        
   19.68 +                        status = get_identity(session, 
   19.69 +                                              null_terminated_address, 
   19.70 +                                              own_id, 
   19.71 +                                              &check_me);
   19.72 +                        free(null_terminated_address);
   19.73 +
   19.74 +                    }
   19.75 +                    else {
   19.76 +                        status = own_id_status;
   19.77 +                    }
   19.78                  } 
   19.79                  else
   19.80                      status = PEP_OUT_OF_MEMORY;
   19.81 @@ -608,10 +628,23 @@
   19.82                              // GroupUpdate and UpdateRequests come from group.
   19.83                              // check trust relation in between signer key and 
   19.84                              // own id to be sure.
   19.85 -                            pEp_identity *_from = new_identity(NULL, 
   19.86 -                                                               keylist->value,
   19.87 -                                                               PEP_OWN_USERID,
   19.88 -                                                               NULL);
   19.89 +                            
   19.90 +                            if (status != PEP_STATUS_OK)
   19.91 +                                goto free_all;
   19.92 +                            
   19.93 +                            pEp_identity* _from = NULL;
   19.94 +                            
   19.95 +                            if (own_id) {    
   19.96 +                                _from = new_identity(NULL, 
   19.97 +                                                     keylist->value,
   19.98 +                                                     own_id,
   19.99 +                                                     NULL);
  19.100 +                            }
  19.101 +                            else {
  19.102 +                                status = own_id_status;
  19.103 +                                goto free_all;
  19.104 +                            }
  19.105 +                            
  19.106                              if (_from == NULL){
  19.107                                  status = PEP_OUT_OF_MEMORY;
  19.108                                  goto free_all;
  19.109 @@ -658,7 +691,7 @@
  19.110                  ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  19.111              free_userid:
  19.112                  free(user_id);
  19.113 -
  19.114 +                free(own_id);
  19.115                  if (status != PEP_STATUS_OK)
  19.116                      return status;
  19.117              }
  19.118 @@ -754,6 +787,7 @@
  19.119      message *_message = NULL;
  19.120      pEp_identity *me = NULL;
  19.121      pEp_identity *_me = NULL;
  19.122 +    char* own_id = NULL;
  19.123  
  19.124      assert(session && partner && state && msg);
  19.125      if (!(session && partner && state && msg))
  19.126 @@ -765,10 +799,14 @@
  19.127          goto error;
  19.128      }
  19.129  
  19.130 +    status = get_default_own_userid(session, &own_id);
  19.131 +    if (status != PEP_STATUS_OK)
  19.132 +        goto error;
  19.133 +
  19.134      msg->header.version.major = SYNC_VERSION_MAJOR;
  19.135      msg->header.version.minor = SYNC_VERSION_MINOR;
  19.136  
  19.137 -    status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
  19.138 +    status = get_identity(session, partner->address, own_id, &me);
  19.139      if (status != PEP_STATUS_OK)
  19.140          goto error;
  19.141      
  19.142 @@ -889,6 +927,7 @@
  19.143      free(payload);
  19.144      free_message(_message);
  19.145      free_identity(me);
  19.146 +    free(own_id);
  19.147      return status;
  19.148  }
  19.149  
    20.1 --- a/src/timestamp.c	Mon Jan 15 12:26:14 2018 +0100
    20.2 +++ b/src/timestamp.c	Mon Jan 29 12:15:51 2018 +0100
    20.3 @@ -30,9 +30,13 @@
    20.4  
    20.5  DYNAMIC_API timestamp * timestamp_dup(const timestamp *src)
    20.6  {
    20.7 +    assert(src);
    20.8 +    if (!src)
    20.9 +        return NULL;
   20.10 +
   20.11      timestamp *dst = malloc(sizeof(timestamp));
   20.12      assert(dst);
   20.13 -    if (dst == NULL)
   20.14 +    if (!dst)
   20.15          return NULL;
   20.16  
   20.17      memcpy(dst, src, sizeof(timestamp));
    21.1 --- a/test/apple_mail_test.cc	Mon Jan 15 12:26:14 2018 +0100
    21.2 +++ b/test/apple_mail_test.cc	Mon Jan 29 12:15:51 2018 +0100
    21.3 @@ -34,9 +34,11 @@
    21.4          
    21.5      const string mailtext = slurp(mailfile);
    21.6      pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", "93D19F24AD6F4C4BA9134AAF84D9217908DB0AEE", PEP_OWN_USERID, "pEp Test Recipient");    
    21.7 +    me->me = true;    
    21.8      PEP_STATUS status = myself(session, me);
    21.9      
   21.10      pEp_identity * you = new_identity("pep.test.apple@pep-project.org", NULL, "TOFU_pep.test.apple@pep-project.org", "pEp Test Recipient");    
   21.11 +    you->me = false;    
   21.12      status = update_identity(session, you);
   21.13  
   21.14      trust_personal_key(session, you);
   21.15 @@ -53,7 +55,12 @@
   21.16      status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   21.17      assert(status == PEP_STATUS_OK);
   21.18      assert(msg_ptr);
   21.19 +    
   21.20 +    update_identity(session, msg_ptr->from);
   21.21 +    update_identity(session, msg_ptr->to->ident);
   21.22 +    
   21.23      final_ptr = msg_ptr;
   21.24 +    
   21.25      status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   21.26      final_ptr = dest_msg ? dest_msg : msg_ptr;
   21.27    
    22.1 --- a/test/blacklist_test.cc	Mon Jan 15 12:26:14 2018 +0100
    22.2 +++ b/test/blacklist_test.cc	Mon Jan 29 12:15:51 2018 +0100
    22.3 @@ -64,6 +64,7 @@
    22.4      cout << "23 is not listed any more.\n";
    22.5  
    22.6      cout << "blacklist only key for identity / unblacklist key / add key" << endl;
    22.7 +
    22.8      
    22.9      // 2797 65A2 FEB5 B7C7 31B8  61D9 3E4C EFD9 F7AF 4684 - this is the blacklisted key in blacklisted_pub.asc
   22.10  
   22.11 @@ -75,8 +76,15 @@
   22.12      PEP_STATUS status7 = import_key(session, keytext.c_str(), keytext.length(), NULL);
   22.13      
   22.14      const char* bl_fpr_1 = "279765A2FEB5B7C731B861D93E4CEFD9F7AF4684";
   22.15 -    const char* bl_fpr_2 = "634FAC4417E9B2A5DC2BD4AAC4AEEBBE7E62701B";
   22.16 +    const char* bl_fpr_2 = "634FAC4417E9B2A5DC2BD4AAC4AEEBBE7E62701B"; 
   22.17      bool is_blacklisted = false;
   22.18 +
   22.19 +    // Clean up from previous runs
   22.20 +    PEP_STATUS status10 = blacklist_is_listed(session, bl_fpr_1, &is_blacklisted);
   22.21 +    if (is_blacklisted) {
   22.22 +        is_blacklisted = false;
   22.23 +        blacklist_delete(session, bl_fpr_1);
   22.24 +    }
   22.25      
   22.26      pEp_identity* blacklisted_identity = new_identity("blacklistedkeys@kgrothoff.org",
   22.27                                                        bl_fpr_1,
   22.28 @@ -85,7 +93,9 @@
   22.29  
   22.30      PEP_STATUS status8 = update_identity(session, blacklisted_identity);
   22.31      
   22.32 -    blacklisted_identity->comm_type = PEP_ct_pEp;
   22.33 +    // THERE IS NO BLACKLISTING OF PEP KEYS
   22.34 +    //blacklisted_identity->comm_type = PEP_ct_pEp;
   22.35 +    blacklisted_identity->comm_type = PEP_ct_OpenPGP_unconfirmed;
   22.36  
   22.37      PEP_STATUS status99 = set_identity(session, blacklisted_identity);
   22.38      
   22.39 @@ -93,16 +103,23 @@
   22.40  
   22.41      PEP_STATUS status999 = update_identity(session, blacklisted_identity);
   22.42  
   22.43 -    assert(blacklisted_identity->comm_type == PEP_ct_pEp);
   22.44 +    assert(blacklisted_identity->comm_type == PEP_ct_OpenPGP);
   22.45  
   22.46      PEP_STATUS status9 = blacklist_add(session, bl_fpr_1);
   22.47 -    PEP_STATUS status10 = blacklist_is_listed(session, bl_fpr_1, &is_blacklisted);
   22.48 +    status10 = blacklist_is_listed(session, bl_fpr_1, &is_blacklisted);
   22.49      PEP_STATUS status11 = update_identity(session, blacklisted_identity);
   22.50 +    if (!(blacklisted_identity->fpr))
   22.51 +        cout << "OK! blacklisted_identity->fpr is empty. Yay!" << endl;
   22.52 +    else if (strcmp(blacklisted_identity->fpr, bl_fpr_2) == 0)
   22.53 +        cout << "OK! While this should be empty, you are probably running " << 
   22.54 +                "this in your home directory instead of the test environment " << 
   22.55 +                "and have leftover keys. This is an acceptable result here then. But you " <<
   22.56 +                "should probably clean up after yourself :)" << endl;
   22.57 +    else
   22.58 +        cout << "Not OK. blacklisted_identity->fpr is " << blacklisted_identity->fpr << "." << endl
   22.59 +             << "Expected it to be empty or (possibly) " << bl_fpr_2 << endl;
   22.60 +    assert(!(blacklisted_identity->fpr) || blacklisted_identity->fpr[0] == '\0'|| (strcmp(blacklisted_identity->fpr, bl_fpr_2) == 0));
   22.61  
   22.62 -    if (strcmp(blacklisted_identity->fpr, ""))
   22.63 -        cout << "blacklisted_identity-> fpr should be empty, but is " << blacklisted_identity->fpr << endl;
   22.64 -    else
   22.65 -        cout << "blacklisted identity's fpr successfully wiped by update_identity" << endl;
   22.66  
   22.67      const string keytext2 = slurp("blacklisted_pub2.asc");
   22.68      PEP_STATUS status14 = import_key(session, keytext2.c_str(), keytext2.length(), NULL);
   22.69 @@ -113,10 +130,11 @@
   22.70                                                         "Blacklist Keypair");
   22.71      PEP_STATUS status15 = update_identity(session, blacklisted_identity2);
   22.72  
   22.73 -    if (strcmp(blacklisted_identity->fpr, bl_fpr_2) == 0)
   22.74 +    assert(blacklisted_identity2->fpr && strcmp(blacklisted_identity2->fpr, bl_fpr_2) == 0);
   22.75 +    if (blacklisted_identity2->fpr && strcmp(blacklisted_identity2->fpr, bl_fpr_2) == 0)
   22.76          cout << "blacklisted identity's fpr successfully replaced by the unblacklisted one" << endl;
   22.77 -    else
   22.78 -        cout << "blacklisted_identity->fpr should be " << bl_fpr_2 << " but is " << blacklisted_identity->fpr << endl;
   22.79 +    // else
   22.80 +    //     cout << "blacklisted_identity->fpr should be " << bl_fpr_2 << " but is " << blacklisted_identity->fpr << endl;
   22.81      
   22.82      PEP_STATUS status12 = blacklist_delete(session, bl_fpr_1);
   22.83      PEP_STATUS status13 = update_identity(session, blacklisted_identity);
    23.1 --- a/test/case_and_dot_address_test.cc	Mon Jan 15 12:26:14 2018 +0100
    23.2 +++ b/test/case_and_dot_address_test.cc	Mon Jan 29 12:15:51 2018 +0100
    23.3 @@ -39,36 +39,42 @@
    23.4      assert(statuspub == PEP_STATUS_OK);
    23.5      assert(statuspriv == PEP_STATUS_OK);
    23.6  
    23.7 -    pEp_identity * alice_id = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
    23.8 -    status = update_identity(session, alice_id);
    23.9 -    assert(alice_id->fpr);
   23.10 -    assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.11 +    pEp_identity * alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
   23.12 +    identity_list* own_id = new_identity_list(alice_id);
   23.13 +    status = initialise_own_identities(session, own_id);
   23.14 +    status = trust_personal_key(session, alice_id);
   23.15 +    pEp_identity * new_alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
   23.16 +    status = update_identity(session, new_alice_id);
   23.17 +    assert(new_alice_id->fpr);
   23.18 +    assert(strcmp(new_alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.19 +    free_identity(new_alice_id);
   23.20      free_identity(alice_id);
   23.21      alice_id = NULL;
   23.22 +    new_alice_id = NULL;
   23.23  
   23.24      alice_id = new_identity(alice_email_case, NULL, PEP_OWN_USERID, "Alice Test");
   23.25 -    status = update_identity(session, alice_id);
   23.26 +    status = myself(session, alice_id);
   23.27      assert(alice_id->fpr);
   23.28      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.29      free_identity(alice_id);
   23.30      alice_id = NULL;
   23.31  
   23.32      alice_id = new_identity(alice_email_dot, NULL, PEP_OWN_USERID, "Alice Test");
   23.33 -    status = update_identity(session, alice_id);
   23.34 +    status = myself(session, alice_id);
   23.35      assert(alice_id->fpr);
   23.36      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.37      free_identity(alice_id);
   23.38      alice_id = NULL;
   23.39  
   23.40      alice_id = new_identity(alice_email_dotless, NULL, PEP_OWN_USERID, "Alice Test");
   23.41 -    status = update_identity(session, alice_id);
   23.42 +    status = myself(session, alice_id);
   23.43      assert(alice_id->fpr);
   23.44      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.45      free_identity(alice_id);
   23.46      alice_id = NULL;
   23.47  
   23.48      alice_id = new_identity(alice_email_case_and_dot, NULL, PEP_OWN_USERID, "Alice Test");
   23.49 -    status = update_identity(session, alice_id);
   23.50 +    status = myself(session, alice_id);
   23.51      assert(alice_id->fpr);
   23.52      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   23.53      free_identity(alice_id);
    24.1 --- a/test/decorate_test.cc	Mon Jan 15 12:26:14 2018 +0100
    24.2 +++ b/test/decorate_test.cc	Mon Jan 29 12:15:51 2018 +0100
    24.3 @@ -10,6 +10,7 @@
    24.4  #include <sstream>
    24.5  #include "mime.h"
    24.6  #include "message_api.h"
    24.7 +#include "test_util.h"
    24.8  
    24.9  using namespace std;
   24.10  
   24.11 @@ -24,11 +25,20 @@
   24.12      assert(session);
   24.13      cout << "init() completed.\n";
   24.14  
   24.15 -    // message_api test code
   24.16 +    const string alice_pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   24.17 +    const string alice_priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
   24.18 +    const string bob_pub_key = slurp("test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc");
   24.19 +    PEP_STATUS statuspub = import_key(session, alice_pub_key.c_str(), alice_pub_key.length(), NULL);
   24.20 +    PEP_STATUS statuspriv = import_key(session, alice_priv_key.c_str(), alice_priv_key.length(), NULL);
   24.21 +    PEP_STATUS statusbob = import_key(session, bob_pub_key.c_str(), bob_pub_key.length(), NULL);
   24.22 +    assert(statuspub == PEP_STATUS_OK);
   24.23 +    assert(statuspriv == PEP_STATUS_OK);
   24.24 +    assert(statusbob == PEP_STATUS_OK);
   24.25  
   24.26      cout << "creating message…\n";
   24.27      pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
   24.28      pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test");
   24.29 +    alice->me = true;
   24.30      identity_list* to_list = new_identity_list(bob); // to bob
   24.31      message* outgoing_message = new_message(PEP_dir_outgoing);
   24.32      assert(outgoing_message);
   24.33 @@ -45,7 +55,7 @@
   24.34      message* encrypted_msg = nullptr;
   24.35      cout << "calling encrypt_message\n";
   24.36      PEP_STATUS status = encrypt_message (session, outgoing_message, NULL, &encrypted_msg, PEP_enc_PGP_MIME, 0);
   24.37 -    cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
   24.38 +    cout << "encrypt_message() returns " << tl_status_string(status) << '.' << endl;
   24.39      assert(status == PEP_STATUS_OK);
   24.40      assert(encrypted_msg);
   24.41      cout << "message encrypted.\n";
    25.1 --- a/test/encrypt_for_identity_test.cc	Mon Jan 15 12:26:14 2018 +0100
    25.2 +++ b/test/encrypt_for_identity_test.cc	Mon Jan 29 12:15:51 2018 +0100
    25.3 @@ -38,6 +38,7 @@
    25.4      cout << "creating message…\n";
    25.5      pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
    25.6      pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test");
    25.7 +    alice->me = true;
    25.8  
    25.9      PEP_STATUS mystatus = myself(session, alice);
   25.10      assert(mystatus == PEP_STATUS_OK);
    26.1 --- a/test/encrypt_missing_private_key_test.cc	Mon Jan 15 12:26:14 2018 +0100
    26.2 +++ b/test/encrypt_missing_private_key_test.cc	Mon Jan 29 12:15:51 2018 +0100
    26.3 @@ -25,46 +25,33 @@
    26.4      assert(status1 == PEP_STATUS_OK);
    26.5      assert(session);
    26.6      cout << "init() completed.\n";
    26.7 -
    26.8 -    // blacklist test code
    26.9 -
   26.10 -    cout << "blacklist only key for identity / add key / check which key is used" << endl;
   26.11      
   26.12 -    // B252066DE0513BECA2954F30E8E18177B28D9B9D - this is the blacklisted key in blacklisted_self.asc
   26.13 -
   26.14 -    const string keytext = slurp("test_keys/priv/blacklist_self.asc");
   26.15 -    
   26.16 -    /* import it into pep */
   26.17 -    PEP_STATUS status7 = import_key(session, keytext.c_str(), keytext.length(), NULL);
   26.18 -    
   26.19 -    const char* bl_fpr_1 = "B252066DE0513BECA2954F30E8E18177B28D9B9D";
   26.20 -    bool is_blacklisted = false;
   26.21 -    
   26.22 -    pEp_identity* blacklisted_identity = new_identity("blacklistself@kgrothoff.org",
   26.23 -                                                      bl_fpr_1,
   26.24 +    pEp_identity* no_key_identity = new_identity("blacklistself@kgrothoff.org",
   26.25 +                                                      NULL,
   26.26                                                        PEP_OWN_USERID,
   26.27                                                        "Blacklist Self");
   26.28 -    PEP_STATUS status8 = myself(session, blacklisted_identity);
   26.29 +    no_key_identity->me = true;
   26.30 +    PEP_STATUS status8 = myself(session, no_key_identity);
   26.31      assert (status8 == PEP_STATUS_OK);
   26.32 -    PEP_STATUS status9 = blacklist_add(session, bl_fpr_1);
   26.33 -    assert (status9 == PEP_STATUS_OK);
   26.34 -    PEP_STATUS status10 = blacklist_is_listed(session, bl_fpr_1, &is_blacklisted);
   26.35 -    assert (status10 == PEP_STATUS_OK);
   26.36 -    PEP_STATUS status11 = myself(session, blacklisted_identity);
   26.37 -    assert (status11 == PEP_STATUS_OK);
   26.38  
   26.39 -    /* identity is blacklisted. Now let's try to encrypt a message. */
   26.40 -    
   26.41 -    const char* new_key = NULL;
   26.42 -    
   26.43 -    const string mailtext = slurp("test_mails/blacklist_no_key.eml");
   26.44 -    
   26.45 +    /* Now let's try to encrypt a message. */
   26.46 +        
   26.47      message* tmp_msg = NULL;
   26.48      message* enc_msg = NULL;
   26.49      
   26.50 +    const string mailtext = slurp("test_mails/blacklist_no_key.eml");
   26.51 +
   26.52      PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg);
   26.53      assert(status == PEP_STATUS_OK);
   26.54      
   26.55 +    status = update_identity(session, tmp_msg->from);
   26.56 +    identity_list* to_list = tmp_msg->to;
   26.57 +
   26.58 +    while (to_list) {
   26.59 +        if (to_list->ident)
   26.60 +            update_identity(session, to_list->ident);
   26.61 +        to_list = to_list->next;
   26.62 +    }
   26.63      
   26.64      // This isn't incoming, though... so we need to reverse the direction
   26.65      tmp_msg->dir = PEP_dir_outgoing;
   26.66 @@ -76,30 +63,12 @@
   26.67                               0);
   26.68      assert(status == PEP_STATUS_OK);
   26.69      
   26.70 -//    PEP_STATUS status69 = MIME_encrypt_message(session, mailtext.c_str(), mailtext.length(), NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   26.71 -//    pEp_identity * me1 = new_identity("blacklist_test@kgrothoff.org", NULL, PEP_OWN_USERID, "Blacklisted Key Message Recipient");    
   26.72  
   26.73 -    new_key = enc_msg->from->fpr;
   26.74 +    char* new_key = enc_msg->from->fpr;
   26.75      cout << "Encrypted with key " << new_key << endl;
   26.76 -    assert (strcasecmp(new_key, bl_fpr_1) != 0);
   26.77 -//     PEP_STATUS status = update_identity(session, me1);
   26.78 -//     message* msg_ptr = nullptr;
   26.79 -//     message* dest_msg = nullptr;
   26.80 -//     stringlist_t* keylist = nullptr;
   26.81 -//     PEP_rating rating;
   26.82 -//     PEP_decrypt_flags_t flags;
   26.83 -//     
   26.84 -//     status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   26.85 -//     assert(status == PEP_STATUS_OK);
   26.86 -//     status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   26.87 -// 
   26.88 -//     PEP_STATUS status12 = update_identity(session, blacklisted_identity);
   26.89 -// 
   26.90 -//     assert(strcasecmp(blacklisted_identity->fpr, new_key) == 0);
   26.91      
   26.92      status = delete_keypair(session, new_key);
   26.93 -    PEP_STATUS status13 = blacklist_delete(session, bl_fpr_1);
   26.94 -    PEP_STATUS status14 = update_identity(session, blacklisted_identity);
   26.95 +    PEP_STATUS status14 = myself(session, no_key_identity);
   26.96  
   26.97      free_message(tmp_msg);    
   26.98      free_message(enc_msg);
    27.1 --- a/test/external_revoke_test.cc	Mon Jan 15 12:26:14 2018 +0100
    27.2 +++ b/test/external_revoke_test.cc	Mon Jan 29 12:15:51 2018 +0100
    27.3 @@ -45,7 +45,6 @@
    27.4      status = myself(session, me);
    27.5      
    27.6      // Create key
    27.7 -
    27.8      cout << "Creating new id for : ";
    27.9      char *uniqname = strdup("AAAAtestuser@testdomain.org");
   27.10      srandom(time(NULL));
   27.11 @@ -71,6 +70,7 @@
   27.12      cout << "---------------------------------------------------------" << endl << endl;
   27.13  
   27.14      cout << "Trusting personal key for " << uniqname << endl;
   27.15 +    recip1->me = false;
   27.16      // Trust it
   27.17      status = update_identity(session, recip1);
   27.18      status = trust_personal_key(session, recip1);
   27.19 @@ -179,53 +179,27 @@
   27.20  
   27.21      status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
   27.22      cout << "Encryption returns with status " << tl_status_string(status) << endl;
   27.23 -
   27.24 -    PEP_comm_type ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
   27.25 +    assert (status == PEP_KEY_UNSUITABLE);
   27.26 +    assert (encrypted_outgoing_msg == NULL);
   27.27 +    status = update_identity(session, recip1);
   27.28 +    assert (recip1->comm_type = PEP_ct_key_revoked);
   27.29  
   27.30      cout << endl << "---------------------------------------------------------" << endl;
   27.31      cout << "2c. Check trust of recip, whose only key has been revoked, once an encryption attempt has been made." << endl;
   27.32      cout << "---------------------------------------------------------" << endl << endl;
   27.33  
   27.34 -    // check comm_type
   27.35 -    cout << "comm_type: " << tl_ct_string(ct) << endl;
   27.36 -    assert(ct == PEP_ct_key_revoked);
   27.37 -    
   27.38 +    assert(recip1->fpr == NULL);
   27.39 +    recip1->fpr = fprs[0];
   27.40      status = get_trust(session, recip1);
   27.41 +    recip1->fpr = NULL;
   27.42  
   27.43      cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
   27.44      assert(recip1->comm_type == PEP_ct_key_revoked);
   27.45  
   27.46 -    cout << endl << "---------------------------------------------------------" << endl;
   27.47 -    cout << "2d. Try to decrypt message that was encrypted for revoked key guy." << endl;
   27.48 -    cout << "---------------------------------------------------------" << endl << endl;
   27.49 -    // decrypt message
   27.50 -//    free_message(outgoing_msg);
   27.51 -//    outgoing_msg = NULL;
   27.52 -    // FIXME: Make this make more sense
   27.53 -    status = decrypt_message(session, outgoing_msg, &decrypted_msg, &keylist, &rating, &flags);
   27.54 -    cout << "Decryption returns with status " << tl_status_string(status) << endl;
   27.55 -    assert(status == PEP_UNENCRYPTED);
   27.56 -    
   27.57 -    // check rating
   27.58 -    cout << "Rating of decrypted message to trusted recip: " << tl_rating_string(rating) << endl;
   27.59 -    assert(rating == PEP_rating_unencrypted);
   27.60 -
   27.61 -    ct = (decrypted_msg ? decrypted_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
   27.62 -
   27.63 -    cout << "comm_type: " << tl_ct_string(ct) << endl;
   27.64 -    assert(ct == PEP_ct_key_revoked);
   27.65 -    
   27.66 -    status = get_trust(session, recip1);
   27.67 -    
   27.68 -    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
   27.69 -    assert(recip1->comm_type == PEP_ct_key_revoked);
   27.70 -
   27.71 -    free_message(encrypted_outgoing_msg);
   27.72      free_message(decrypted_msg);
   27.73      free_message(outgoing_msg);
   27.74      outgoing_msg = NULL;
   27.75      decrypted_msg = NULL;
   27.76 -    encrypted_outgoing_msg = NULL;
   27.77  
   27.78      cout << endl << "---------------------------------------------------------" << endl;
   27.79      cout << "3a. Generate new key, but don't explicitly trust it." << endl;
   27.80 @@ -261,7 +235,7 @@
   27.81      cout << "Message created.\n";
   27.82  
   27.83      status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
   27.84 -    ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
   27.85 +    PEP_comm_type ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
   27.86      
   27.87  
   27.88      // CHECK STATUS???
   27.89 @@ -273,8 +247,8 @@
   27.90      
   27.91      status = get_trust(session, recip1);
   27.92  
   27.93 -    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
   27.94 -    assert(recip1->comm_type == PEP_ct_OpenPGP_unconfirmed);
   27.95 +    cout << "Recip's trust DB comm_type (should be unknown, as we're using a keyring-only key, not in DB) = " << hex << tl_ct_string(recip1->comm_type) << endl;
   27.96 +    assert(recip1->comm_type != PEP_ct_OpenPGP_unconfirmed);
   27.97  
   27.98      // decrypt message
   27.99  //    free_message(outgoing_msg);
  27.100 @@ -302,8 +276,8 @@
  27.101      
  27.102      status = get_trust(session, recip1);
  27.103      
  27.104 -    cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
  27.105 -    assert(recip1->comm_type == PEP_ct_OpenPGP_unconfirmed);
  27.106 +    cout << "Recip's trust DB comm_type (should be unknown - there's nothing in the DB) = " << hex << tl_ct_string(recip1->comm_type) << endl;
  27.107 +    assert(recip1->comm_type == PEP_ct_unknown);
  27.108  
  27.109      free_message(encrypted_outgoing_msg);
  27.110      free_message(decrypted_msg);
    28.1 --- a/test/identity_list_test.cc	Mon Jan 15 12:26:14 2018 +0100
    28.2 +++ b/test/identity_list_test.cc	Mon Jan 29 12:15:51 2018 +0100
    28.3 @@ -20,6 +20,7 @@
    28.4      PEP_comm_type comm_type;    // type of communication with this ID
    28.5      char lang[3];               // language of conversation
    28.6                                  // ISO 639-1 ALPHA-2, last byte is 0
    28.7 +-    bool me;                    // if this is the local user herself/himself
    28.8      */
    28.9  
   28.10  int test_identity_equals(pEp_identity* val1, pEp_identity* val2) {
   28.11 @@ -34,7 +35,7 @@
   28.12      return((strcmp(val1->address, val2->address) == 0) && (strcmp(val1->fpr, val2->fpr) == 0)
   28.13          && (strcmp(val1->username, val2->username) == 0) && (val1->comm_type == val2->comm_type)
   28.14          && (val1->lang[0] == val2->lang[0]) && (val1->lang[1] == val2->lang[1])
   28.15 -        && (val1->lang[2] == val2->lang[2]));
   28.16 +        && (val1->lang[2] == val2->lang[2]) && (val1->me == val2->me));
   28.17  }
   28.18  
   28.19  int main() {
    29.1 --- a/test/least_color_group_test.cc	Mon Jan 15 12:26:14 2018 +0100
    29.2 +++ b/test/least_color_group_test.cc	Mon Jan 29 12:15:51 2018 +0100
    29.3 @@ -46,9 +46,8 @@
    29.4      pEp_identity * me1 = new_identity("pep.color.test.P@kgrothoff.org", 
    29.5                                        "7EE6C60C68851954E1797F81EA59715E3EBE215C", 
    29.6                                        PEP_OWN_USERID, "Pep Color Test P (recip)");
    29.7 -    PEP_STATUS status = update_identity(session, me1);
    29.8 -    trust_personal_key(session, me1);
    29.9 -    status = update_identity(session, me1);
   29.10 +    me1->me = true;
   29.11 +    PEP_STATUS status = myself(session, me1);
   29.12      
   29.13      pEp_identity * sender1 = new_identity("pep.color.test.V@kgrothoff.org",
   29.14                                            NULL, "TOFU_pep.color.test.V@kgrothoff.org",
    30.1 --- a/test/least_common_denom_color_test.cc	Mon Jan 15 12:26:14 2018 +0100
    30.2 +++ b/test/least_common_denom_color_test.cc	Mon Jan 29 12:15:51 2018 +0100
    30.3 @@ -36,14 +36,17 @@
    30.4      PEP_STATUS statuskey4 = import_key(session, keytextkey4.c_str(), keytextkey4.length(), NULL);
    30.5  
    30.6      pEp_identity * sender = new_identity("pep.never.me.test@kgrothoff.org", NULL, "TOFU_pep.never.me.test@kgrothoff.org", "pEp Never Me Test");    
    30.7 +    sender->me = false;    
    30.8      PEP_STATUS status = update_identity(session, sender);
    30.9          
   30.10      // reset the trust on both keys before we start
   30.11      pEp_identity * recip1 = new_identity("banmeonce@kgrothoff.org", NULL, "TOFU_banemeonce@kgrothoff.org", "Ban Me Once");    
   30.12 +    recip1->me = false;    
   30.13      status = update_identity(session, recip1);
   30.14      key_reset_trust(session, recip1);
   30.15      
   30.16      pEp_identity * recip2 = new_identity("banmetwice@kgrothoff.org", NULL, "TOFU_banemetwice@kgrothoff.org", "Ban Me Twice");    
   30.17 +    recip2->me = false;    
   30.18      status = update_identity(session, recip2);
   30.19      key_reset_trust(session, recip2);
   30.20          
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/message_2.0_test.cc	Mon Jan 29 12:15:51 2018 +0100
    31.3 @@ -0,0 +1,168 @@
    31.4 +// This file is under GNU General Public License 3.0
    31.5 +// see LICENSE.txt
    31.6 +
    31.7 +#include <stdlib.h>
    31.8 +#include <string.h>
    31.9 +#include "platform.h"
   31.10 +#include <iostream>
   31.11 +#include <fstream>
   31.12 +#include <assert.h>
   31.13 +#include "mime.h"
   31.14 +#include "message_api.h"
   31.15 +#include "keymanagement.h"
   31.16 +#include "test_util.h"
   31.17 +
   31.18 +using namespace std;
   31.19 +
   31.20 +int main() {
   31.21 +    cout << "\n*** message_2.0_test ***\n\n";
   31.22 +
   31.23 +    PEP_SESSION session;
   31.24 +    
   31.25 +    cout << "calling init()\n";
   31.26 +    PEP_STATUS status1 = init(&session);
   31.27 +    assert(status1 == PEP_STATUS_OK);
   31.28 +    assert(session);
   31.29 +    cout << "init() completed.\n";
   31.30 +
   31.31 +    PEP_comm_type carol_comm_type = PEP_ct_OpenPGP_unconfirmed;
   31.32 +
   31.33 +    // message_api test code
   31.34 +
   31.35 +    const string alice_pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   31.36 +    const string alice_priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
   31.37 +    const string carol_pub_key = slurp("test_keys/pub/pep-test-carol-0x42A85A42_pub.asc");
   31.38 +    const string carol_priv_key = slurp("test_keys/priv/pep-test-carol-0x42A85A42_priv.asc");
   31.39 +
   31.40 +    PEP_STATUS statuspub = import_key(session, alice_pub_key.c_str(), alice_pub_key.length(), NULL);
   31.41 +    PEP_STATUS statuspriv = import_key(session, alice_priv_key.c_str(), alice_priv_key.length(), NULL);
   31.42 +    assert(statuspub == PEP_STATUS_OK);
   31.43 +    assert(statuspriv == PEP_STATUS_OK);
   31.44 +    statuspub = import_key(session, carol_pub_key.c_str(), carol_pub_key.length(), NULL);
   31.45 +    statuspriv = import_key(session, carol_priv_key.c_str(), carol_priv_key.length(), NULL);
   31.46 +    assert(statuspub == PEP_STATUS_OK);
   31.47 +    assert(statuspriv == PEP_STATUS_OK);
   31.48 +
   31.49 +    cout << "creating message…\n";
   31.50 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
   31.51 +    pEp_identity* carol = new_identity("pep-test-carol@pep-project.org", NULL, "TOFU_pep-test-carol@pep-project.org", "Carol Test");
   31.52 +
   31.53 +    PEP_STATUS alice_status = update_identity(session, alice);
   31.54 +    PEP_STATUS carol_status = update_identity(session, carol);
   31.55 +
   31.56 +    PEP_STATUS status = update_trust_for_fpr(session, alice->fpr, PEP_ct_pEp);
   31.57 +    status = update_trust_for_fpr(session, carol->fpr, carol_comm_type);
   31.58 +    
   31.59 +    PEP_STATUS mystatus = myself(session, alice);
   31.60 +    assert(mystatus == PEP_STATUS_OK);
   31.61 +    alice_status = update_identity(session, alice);
   31.62 +    alice_status = update_identity(session, carol);
   31.63 +    assert(alice->comm_type == PEP_ct_pEp);
   31.64 +    assert(carol->comm_type == carol_comm_type);
   31.65 +    
   31.66 +    identity_list* to_list = new_identity_list(carol); // to carol
   31.67 +    message* outgoing_message = new_message(PEP_dir_outgoing);
   31.68 +    assert(outgoing_message);
   31.69 +    outgoing_message->from = alice;
   31.70 +    outgoing_message->to = to_list;
   31.71 +    outgoing_message->shortmsg = strdup("Greetings, humans!");
   31.72 +    outgoing_message->longmsg = strdup("This is a test of the emergency message system. This is only a test. BEEP.");
   31.73 +    outgoing_message->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   31.74 +//    outgoing_message->id = strdup("blahblahyourmama@pep-project.org");
   31.75 +    outgoing_message->references = new_stringlist("one-839274982347239847@pep-project.org");
   31.76 +    stringlist_add(outgoing_message->references, "two-dfddffd839274982347239847@pep-project.org");
   31.77 +    stringlist_add(outgoing_message->references, "three-OMGWTFBBQ.edfddffd839274982347239847@pep-project.org");
   31.78 +    
   31.79 +    cout << "message created.\n";
   31.80 +
   31.81 +    char* encoded_text = nullptr;
   31.82 +    status = mime_encode_message(outgoing_message, false, &encoded_text);
   31.83 +    assert(status == PEP_STATUS_OK);
   31.84 +    assert(encoded_text);
   31.85 +
   31.86 +    cout << "unencrypted:\n\n";
   31.87 +    cout << encoded_text << "\n";
   31.88 +
   31.89 +    free(encoded_text);
   31.90 +
   31.91 +    cout << "encrypting message as MIME multipart…\n";
   31.92 +    message* encrypted_msg = nullptr;
   31.93 +    cout << "calling encrypt_message\n";
   31.94 +    status = encrypt_message(session, outgoing_message, NULL, 
   31.95 +        &encrypted_msg, PEP_enc_PGP_MIME, 0);
   31.96 +    cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
   31.97 +    assert(status == PEP_STATUS_OK);
   31.98 +    assert(encrypted_msg);
   31.99 +    cout << "message encrypted.\n";
  31.100 +    
  31.101 +    encrypted_msg->enc_format = PEP_enc_none;
  31.102 +    status = mime_encode_message(encrypted_msg, false, &encoded_text);
  31.103 +    assert(status == PEP_STATUS_OK);
  31.104 +    assert(encoded_text);
  31.105 +     
  31.106 +    cout << "encrypted:\n\n";
  31.107 +    cout << encoded_text << "\n";
  31.108 +     
  31.109 +    char* decrypted_text;
  31.110 +    
  31.111 +    message* decrypted_msg = nullptr;
  31.112 +    stringlist_t* keylist_used = nullptr;
  31.113 +    
  31.114 +    PEP_rating rating;
  31.115 +    PEP_decrypt_flags_t flags;
  31.116 +     
  31.117 +//    MIME_decrypt_message(session, encoded_text, strlen(encoded_text), &decrypted_text, &keylist_used, &rating, &flags);
  31.118 +    
  31.119 +//    cout << "HEY!" << endl;
  31.120 +//    cout << decrypted_text << endl;
  31.121 +    
  31.122 +    message* decoded_msg = nullptr;
  31.123 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
  31.124 +    assert(status == PEP_STATUS_OK);
  31.125 +    const string string3 = encoded_text;
  31.126 +      
  31.127 +    unlink("msg_2.0.asc");
  31.128 +    ofstream outFile3("msg_2.0.asc");
  31.129 +    outFile3.write(string3.c_str(), string3.size());
  31.130 +    outFile3.close();
  31.131 +    
  31.132 +    // message* decrypted_msg = nullptr;
  31.133 +    // stringlist_t* keylist_used = nullptr;
  31.134 +    // 
  31.135 +    // PEP_rating rating;
  31.136 +    // PEP_decrypt_flags_t flags;
  31.137 +    // 
  31.138 +    stringpair_t* autoconsume = new_stringpair("pEp-auto-consume", "yes");
  31.139 +    stringpair_list_add(encrypted_msg->opt_fields, autoconsume);
  31.140 +    status = decrypt_message(session, encrypted_msg, &decrypted_msg, &keylist_used, &rating, &flags);
  31.141 +    assert(decrypted_msg);
  31.142 +    assert(keylist_used);
  31.143 +    assert(rating);
  31.144 +    //assert(status == PEP_STATUS_OK && rating == PEP_rating_reliable);
  31.145 +    //PEP_comm_type ct = encrypted_msg->from->comm_type;
  31.146 +    //assert(ct == PEP_ct_pEp);
  31.147 +    
  31.148 +    cout << "keys used:\n";
  31.149 +    
  31.150 +    for (stringlist_t* kl4 = keylist_used; kl4 && kl4->value; kl4 = kl4->next)
  31.151 +    {
  31.152 +       cout << "\t " << kl4->value << endl;
  31.153 +    }
  31.154 +     
  31.155 +    decrypted_msg->enc_format = PEP_enc_none; 
  31.156 +    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false);
  31.157 +    assert(status == PEP_STATUS_OK);
  31.158 +    assert(encoded_text);
  31.159 +    cout << "Decrypted message: " << endl;
  31.160 +    cout << encoded_text << endl;
  31.161 +     
  31.162 +    cout << "freeing messages…\n";
  31.163 +    free_message(encrypted_msg);
  31.164 +    free_message(decrypted_msg);
  31.165 +    free_message(outgoing_message);
  31.166 +    cout << "done.\n";
  31.167 +    
  31.168 +    cout << "calling release()\n";
  31.169 +    release(session);
  31.170 +    return 0;
  31.171 +}
    32.1 --- a/test/message_api_test.cc	Mon Jan 15 12:26:14 2018 +0100
    32.2 +++ b/test/message_api_test.cc	Mon Jan 29 12:15:51 2018 +0100
    32.3 @@ -147,6 +147,7 @@
    32.4  	
    32.5  	std::cout << "MIME_decrypt_message returned " << std::dec << status2 << std::hex << " (0x" << status2 << ")" << std::dec << endl;
    32.6  	
    32.7 +    // We have no public key, so we cannot, in fact, VERIFY the message. SO cannot be PEP_STATUS_OK.
    32.8  	assert(status2 == PEP_DECRYPTED);
    32.9  	assert(plaintext);
   32.10  	
   32.11 @@ -162,7 +163,6 @@
   32.12  	free_identity_list(pk);
   32.13  }
   32.14  
   32.15 -
   32.16  int main() {
   32.17      cout << "\n*** message_api_test ***\n\n";
   32.18      test_MIME_decrypt_message();
   32.19 @@ -180,6 +180,7 @@
   32.20      cout << "creating message…\n";
   32.21      pEp_identity * me2 = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice Test");
   32.22      // pEp_identity * me2 = new_identity("test@nokey.plop", NULL, PEP_OWN_USERID, "Test no key");
   32.23 +    me2->me = true;
   32.24      identity_list *to2 = new_identity_list(new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test"));
   32.25      // identity_list *to2 = new_identity_list(new_identity("still@nokey.blup", NULL, "42", "Still no key"));
   32.26      message *msg2 = new_message(PEP_dir_outgoing);
    33.1 --- a/test/mistrust_undo_test.cc	Mon Jan 15 12:26:14 2018 +0100
    33.2 +++ b/test/mistrust_undo_test.cc	Mon Jan 29 12:15:51 2018 +0100
    33.3 @@ -40,8 +40,12 @@
    33.4      assert(status == PEP_STATUS_OK);
    33.5      assert(strcmp(recip1->fpr, "BACC7A60A88A39A25D99B4A545D7542F39E5DAB5") == 0);
    33.6      
    33.7 +    // First, we need the fpr to be in the DB system.
    33.8 +    status = set_identity(session,recip1);
    33.9 +    // Then we update the trust.
   33.10      // This is not an external function. We use it to expedite the test since we don't do a sync exchange here.
   33.11      status = update_trust_for_fpr(session, recip1->fpr, PEP_ct_pEp);
   33.12 +    // Then we retrieve the new trust.
   33.13      status = update_identity(session,recip1);
   33.14      assert(status == PEP_STATUS_OK);
   33.15      assert(recip1->comm_type == PEP_ct_pEp);
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/test/new_update_id_and_myself_test.cc	Mon Jan 29 12:15:51 2018 +0100
    34.3 @@ -0,0 +1,512 @@
    34.4 +// This file is under GNU General Public License 3.0
    34.5 +// see LICENSE.txt
    34.6 +
    34.7 +#include <iostream>
    34.8 +#include <iostream>
    34.9 +#include <fstream>
   34.10 +#include <string>
   34.11 +#include <cstring> // for strcmp()
   34.12 +#include <assert.h>
   34.13 +#include "pEpEngine.h"
   34.14 +#include "message_api.h"
   34.15 +#include "keymanagement.h"
   34.16 +#include "test_util.h"
   34.17 +
   34.18 +using namespace std;
   34.19 +
   34.20 +int main() {
   34.21 +    cout << "\n*** test update_identity and myself ***\n\n";
   34.22 +    
   34.23 +    PEP_SESSION session;
   34.24 +    
   34.25 +    cout << "calling init()\n";
   34.26 +    PEP_STATUS status = init(&session);
   34.27 +    assert(status == PEP_STATUS_OK);
   34.28 +    assert(session);
   34.29 +    cout << "init() completed.\n";
   34.30 +    cout << endl;
   34.31 +    cout << "***********************************************************************" << endl;
   34.32 +    cout << "* Section I. myself()" << endl;
   34.33 +    cout << "***********************************************************************" << endl << endl;
   34.34 +
   34.35 +    // Create id with no key
   34.36 +    cout << "Creating new own id with no key for : ";
   34.37 +    char *uniqname = strdup("AAAAtestuser@testdomain.org");
   34.38 +    srandom(time(NULL));
   34.39 +    for(int i=0; i < 4;i++)
   34.40 +        uniqname[i] += random() & 0xf;
   34.41 +    
   34.42 +    cout << uniqname << "\n";
   34.43 +    
   34.44 +    const char* own_user_id = "FineOwnIdentitiesOfBuckTFerris";
   34.45 +    const char* start_username = "Unser Testkandidat";
   34.46 +
   34.47 +    pEp_identity * new_me = new_identity(uniqname, NULL, own_user_id, start_username);
   34.48 +    
   34.49 +    cout << "***********************************************************************" << endl;
   34.50 +    cout << "* I: 1. myself() on id with no record in the DB and no input fpr" << endl;
   34.51 +    cout << "***********************************************************************" << endl << endl;
   34.52 +    status = myself(session, new_me);
   34.53 +    assert(status == PEP_STATUS_OK);
   34.54 +    assert(new_me->fpr);
   34.55 +    
   34.56 +    cout << "PASS: myself() generated fingerprint ";
   34.57 +    cout << new_me->fpr << endl << endl;
   34.58 +
   34.59 +    char* generated_fpr = strdup(new_me->fpr);
   34.60 +    
   34.61 +    assert(new_me->comm_type == PEP_ct_pEp);
   34.62 +    
   34.63 +    free_identity(new_me);
   34.64 +
   34.65 +    cout << "***********************************************************************" << endl;
   34.66 +    cout << "* I: 2. myself() on id with no input fpr and a record in the DB" << endl;
   34.67 +    cout << "***********************************************************************" << endl << endl;
   34.68 +
   34.69 +    new_me = new_identity(uniqname, NULL, own_user_id, NULL);
   34.70 +    status = myself(session, new_me);
   34.71 +    assert(status == PEP_STATUS_OK);
   34.72 +    
   34.73 +    assert(new_me->fpr);
   34.74 +    assert(strcmp(new_me->fpr, generated_fpr) == 0);
   34.75 +    assert(new_me->username);
   34.76 +    assert(strcmp(new_me->username, start_username) == 0);
   34.77 +    assert(new_me->user_id);
   34.78 +    assert(new_me->comm_type == PEP_ct_pEp);
   34.79 +    
   34.80 +    char* default_own_id = NULL;
   34.81 +    status = get_userid_alias_default(session, own_user_id, &default_own_id);
   34.82 +    if (status == PEP_CANNOT_FIND_ALIAS) {
   34.83 +        // Ok, we presume our own id above is the default (should be true if there was no existing DB as in test env)
   34.84 +        default_own_id = strdup(own_user_id);
   34.85 +    }
   34.86 +
   34.87 +    assert(strcmp(new_me->user_id, default_own_id) == 0);
   34.88 +    
   34.89 +    cout << "PASS: myself() retrieved the correct fpr, username and default user id" << endl << endl;
   34.90 +
   34.91 +    free_identity(new_me);
   34.92 +     
   34.93 +    cout << "****************************************************************************************" << endl;
   34.94 +    cout << "* I: 3. myself() on id with no input fpr, a different user_id, and a record in the DB" << endl;
   34.95 +    cout << "****************************************************************************************" << endl << endl;
   34.96 +
   34.97 +    const char* alias_id = "Huss Es El Mejor Presidente Del Mundo!";
   34.98 +
   34.99 +    new_me = new_identity(uniqname, NULL, alias_id, NULL);
  34.100 +    status = myself(session, new_me);
  34.101 +    assert(status == PEP_STATUS_OK);
  34.102 +    
  34.103 +    assert(new_me->fpr);
  34.104 +    assert(strcmp(new_me->fpr, generated_fpr) == 0);
  34.105 +    assert(new_me->username);
  34.106 +    assert(strcmp(new_me->username, start_username) == 0);
  34.107 +    assert(new_me->user_id);
  34.108 +    assert(strcmp(new_me->user_id, default_own_id) == 0);
  34.109 +    assert(new_me->comm_type == PEP_ct_pEp);
  34.110 +    
  34.111 +    char* tmp_def = NULL;
  34.112 +    
  34.113 +    status = get_userid_alias_default(session, alias_id, &tmp_def);
  34.114 +    assert(status == PEP_STATUS_OK);
  34.115 +    assert(strcmp(tmp_def, default_own_id) == 0);
  34.116 +
  34.117 +    cout << "PASS: myself() retrieved the correct fpr, username and default user id, and put the right alias in for the default";
  34.118 +    cout << endl << endl;
  34.119 +    
  34.120 +    free(tmp_def);
  34.121 +    free_identity(new_me);
  34.122 +
  34.123 +    cout << "****************************************************************************************" << endl;
  34.124 +    cout << "* I: 4. myself(), replace fpr" << endl;
  34.125 +    cout << "****************************************************************************************" << endl << endl;
  34.126 +
  34.127 +    new_me = new_identity(uniqname, NULL, alias_id, start_username);
  34.128 +    status = generate_keypair(session, new_me);
  34.129 +    assert(new_me->fpr);
  34.130 +    
  34.131 +    cout << "Generated fingerprint ";
  34.132 +    cout << new_me->fpr << "\n";
  34.133 +
  34.134 +    char* new_fpr = strdup(new_me->fpr);
  34.135 +
  34.136 +    new_me = new_identity(uniqname, new_fpr, alias_id, NULL);
  34.137 +
  34.138 +    status = myself(session, new_me);
  34.139 +    assert(status == PEP_STATUS_OK);
  34.140 +    assert(new_me->fpr);
  34.141 +    assert(strcmp(new_me->fpr, generated_fpr) != 0);
  34.142 +    assert(strcmp(new_me->fpr, new_fpr) == 0);
  34.143 +    assert(new_me->username);
  34.144 +    assert(strcmp(new_me->username, start_username) == 0);
  34.145 +    assert(new_me->user_id);
  34.146 +    assert(strcmp(new_me->user_id, default_own_id) == 0);
  34.147 +    assert(new_me->me);
  34.148 +    assert(new_me->comm_type == PEP_ct_pEp);
  34.149 +
  34.150 +    cout << "PASS: myself() set and retrieved the new fpr, username and default user id, and put the right alias in for the default";
  34.151 +    cout << endl << endl;
  34.152 +
  34.153 +    // since that worked, we'll set it back as the default
  34.154 +    free(new_me->fpr);
  34.155 +    new_me->fpr = strdup(generated_fpr);
  34.156 +    new_me->comm_type = PEP_ct_unknown;
  34.157 +    status = myself(session, new_me);
  34.158 +    assert(status == PEP_STATUS_OK);
  34.159 +    assert(strcmp(new_me->fpr, generated_fpr) == 0);
  34.160 +    assert(new_me->comm_type == PEP_ct_pEp);
  34.161 +    
  34.162 +    cout << "****************************************************************************************" << endl;
  34.163 +    cout << "* I: 5. myself(), replace fpr, revoke key" << endl;
  34.164 +    cout << "****************************************************************************************" << endl << endl;
  34.165 +
  34.166 +    status = revoke_key(session, generated_fpr, "Because it's fun");
  34.167 +    assert (status == PEP_STATUS_OK);
  34.168 +    
  34.169 +    new_me = new_identity(uniqname, new_fpr, alias_id, NULL);
  34.170 +    
  34.171 +    status = myself(session, new_me);
  34.172 +    assert(status == PEP_STATUS_OK);
  34.173 +    assert(new_me->fpr);
  34.174 +    assert(strcmp(new_me->fpr, generated_fpr) != 0);
  34.175 +    assert(new_me->username);
  34.176 +    assert(strcmp(new_me->username, start_username) == 0);
  34.177 +    assert(new_me->user_id);
  34.178 +    assert(strcmp(new_me->user_id, default_own_id) == 0);
  34.179 +    assert(new_me->me);
  34.180 +    assert(new_me->comm_type == PEP_ct_pEp);
  34.181 +    
  34.182 +    cout << "PASS: myself() retrieved the new fpr, username and default user id, and put the right alias in for the default";
  34.183 +    cout << endl << endl;
  34.184 +        
  34.185 +    cout << "***********************************************************************" << endl;
  34.186 +    cout << "* Section II. update_identity()" << endl;
  34.187 +    cout << "***********************************************************************" << endl << endl;
  34.188 +
  34.189 +    cout << "****************************************************************************************" << endl;
  34.190 +    cout << "* II: 1. update_identity() - get identity with matching address and user_id and username" << endl;
  34.191 +    cout << "****************************************************************************************" << endl << endl;    
  34.192 +    // 1. create original identity
  34.193 +    const char* alex_address = "pep.test.alexander@peptest.ch";
  34.194 +    const char* alex_fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
  34.195 +    const char* alex_userid = "Alex";
  34.196 +    const char* alex_username = "SuperDuperAlex";
  34.197 +    const string alex_pub_key = slurp("test_keys/pub/pep.test.alexander-0x26B54E4E_pub.asc");
  34.198 +    
  34.199 +    PEP_STATUS statuspub = import_key(session, alex_pub_key.c_str(), alex_pub_key.length(), NULL);
  34.200 +    assert(statuspub == PEP_STATUS_OK);
  34.201 +
  34.202 +    pEp_identity* alex = new_identity(alex_address, alex_fpr, alex_userid, alex_username);
  34.203 +
  34.204 +    // 2. set identity
  34.205 +    status = set_identity(session, alex);
  34.206 +    assert(status == PEP_STATUS_OK);
  34.207 +    free_identity(alex);
  34.208 +            
  34.209 +    alex = new_identity(alex_address, NULL, alex_userid, alex_username); 
  34.210 +    status = update_identity(session, alex);
  34.211 +    assert(status == PEP_STATUS_OK);
  34.212 +    assert(alex->fpr);
  34.213 +    assert(strcmp(alex->fpr, alex_fpr) == 0);
  34.214 +    assert(alex->username);
  34.215 +    assert(strcmp(alex->username, alex_username) == 0);
  34.216 +    assert(alex->user_id);
  34.217 +    assert(strcmp(alex->user_id, alex_userid) == 0);
  34.218 +    assert(!alex->me); 
  34.219 +    assert(alex->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.220 +    assert(strcmp(alex->address, alex_address) == 0);
  34.221 +
  34.222 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address, id, and username" << endl << endl;
  34.223 +    free_identity(alex);
  34.224 +
  34.225 +    cout << "****************************************************************************************" << endl;
  34.226 +    cout << "* II: 2. update_identity() - get identity with matching address and user_id and new username" << endl;
  34.227 +    cout << "****************************************************************************************" << endl << endl;    
  34.228 +
  34.229 +    const char* new_username = "Test Patchy";
  34.230 +            
  34.231 +    alex = new_identity(alex_address, NULL, alex_userid, new_username); 
  34.232 +    status = update_identity(session, alex);
  34.233 +    assert(status == PEP_STATUS_OK);
  34.234 +    assert(alex->fpr);
  34.235 +    assert(strcmp(alex->fpr, alex_fpr) == 0);
  34.236 +    assert(alex->username);
  34.237 +    assert(strcmp(alex->username, new_username) == 0);
  34.238 +    assert(alex->user_id);
  34.239 +    assert(strcmp(alex->user_id, alex_userid) == 0);
  34.240 +    assert(!alex->me); 
  34.241 +    assert(alex->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.242 +    assert(strcmp(alex->address, alex_address) == 0);
  34.243 +
  34.244 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address and id, and patched username" << endl << endl;
  34.245 +    free_identity(alex);
  34.246 +
  34.247 +    cout << "****************************************************************************************" << endl;
  34.248 +    cout << "* II: 3. update_identity() - get identity with matching address and user_id only" << endl;
  34.249 +    cout << "****************************************************************************************" << endl << endl;    
  34.250 +        
  34.251 +    alex = new_identity(alex_address, NULL, alex_userid, NULL); 
  34.252 +    status = update_identity(session, alex);
  34.253 +    assert(status == PEP_STATUS_OK);
  34.254 +    assert(alex->fpr);
  34.255 +    assert(strcmp(alex->fpr, alex_fpr) == 0);
  34.256 +    assert(alex->username);
  34.257 +    assert(strcmp(alex->username, new_username) == 0);
  34.258 +    assert(alex->user_id);
  34.259 +    assert(strcmp(alex->user_id, alex_userid) == 0);
  34.260 +    assert(!alex->me); 
  34.261 +    assert(alex->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.262 +    assert(strcmp(alex->address, alex_address) == 0);
  34.263 +
  34.264 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address and id, and patched username" << endl << endl;
  34.265 +    free_identity(alex);
  34.266 +
  34.267 +    cout << "****************************************************************************************" << endl;
  34.268 +    cout << "* II: 4. update_identity() - get identity with just address and username" << endl;
  34.269 +    cout << "****************************************************************************************" << endl << endl;    
  34.270 +
  34.271 +    alex = new_identity(alex_address, NULL, NULL, new_username); 
  34.272 +    status = update_identity(session, alex);
  34.273 +    assert(status == PEP_STATUS_OK);
  34.274 +    assert(alex->fpr);
  34.275 +    assert(strcmp(alex->fpr, alex_fpr) == 0);
  34.276 +    assert(alex->username);
  34.277 +    assert(strcmp(alex->username, new_username) == 0);
  34.278 +    assert(alex->user_id);
  34.279 +    assert(strcmp(alex->user_id, alex_userid) == 0);
  34.280 +    assert(!alex->me); 
  34.281 +    assert(alex->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.282 +    assert(strcmp(alex->address, alex_address) == 0);
  34.283 +
  34.284 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address and username" << endl << endl;
  34.285 +    free_identity(alex);
  34.286 +
  34.287 +    cout << "****************************************************************************************" << endl;
  34.288 +    cout << "* II: 5. update_identity() with just address " << endl;
  34.289 +    cout << "****************************************************************************************" << endl << endl;
  34.290 +    
  34.291 +    alex = new_identity(alex_address, NULL, NULL, NULL); 
  34.292 +    status = update_identity(session, alex);
  34.293 +    assert(status == PEP_STATUS_OK);
  34.294 +    assert(alex->fpr);
  34.295 +    assert(strcmp(alex->fpr, alex_fpr) == 0);
  34.296 +    assert(alex->username);
  34.297 +    assert(strcmp(alex->username, new_username) == 0);
  34.298 +    assert(alex->user_id);
  34.299 +    assert(strcmp(alex->user_id, alex_userid) == 0);
  34.300 +    assert(!alex->me); 
  34.301 +    assert(alex->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.302 +    assert(strcmp(alex->address, alex_address) == 0);
  34.303 +
  34.304 +    cout << "PASS: update_identity() correctly retrieved extant record with just matching address. Retrieved previously patched username." << endl << endl;
  34.305 +    free_identity(alex);
  34.306 +
  34.307 +
  34.308 +    cout << "****************************************************************************************" << endl;
  34.309 +    cout << "* II: 6. update_identity() with just address on own identity (only case where this is legal)" << endl;
  34.310 +    cout << "****************************************************************************************" << endl << endl;
  34.311 +    
  34.312 +    pEp_identity* somebody = new_identity(uniqname, NULL, NULL, NULL); 
  34.313 +    status = update_identity(session, somebody);
  34.314 +    assert(status == PEP_STATUS_OK);
  34.315 +    myself(session, somebody);
  34.316 +    assert(somebody->fpr);
  34.317 +    assert(strcmp(somebody->fpr, new_fpr) == 0);
  34.318 +    assert(somebody->username);
  34.319 +    assert(strcmp(somebody->username, start_username) == 0);
  34.320 +    assert(somebody->user_id);
  34.321 +    assert(strcmp(somebody->user_id, default_own_id) == 0);
  34.322 +    assert(somebody->me); // true in this case, as it was an own identity
  34.323 +    assert(somebody->comm_type == PEP_ct_pEp);
  34.324 +    assert(strcmp(somebody->address, uniqname) == 0);
  34.325 +    
  34.326 +    cout << "PASS: update_identity() retrieved the right identity information given just an address";
  34.327 +    cout << endl << endl;
  34.328 +
  34.329 +    free_identity(somebody);
  34.330 +
  34.331 +    cout << "****************************************************************************************" << endl;
  34.332 +    cout << "* II: 7. update_identity() for address and user_id that don't exist" << endl;
  34.333 +    cout << "****************************************************************************************" << endl << endl;
  34.334 +
  34.335 +    somebody = new_identity("nope@nope.nope", NULL, "some_user_id", NULL); 
  34.336 +    status = update_identity(session, somebody);
  34.337 +    assert(status == PEP_CANNOT_FIND_IDENTITY);
  34.338 +    cout << "PASS: update_identity() returns PEP_CANNOT_FIND_IDENTITY" << endl << endl;
  34.339 +
  34.340 +    free_identity(somebody);
  34.341 +    
  34.342 +    cout << "****************************************************************************************" << endl;
  34.343 +    cout << "* II: 8. update_identity() for address and and username, but non-matching temp user_id" << endl;
  34.344 +    cout << "****************************************************************************************" << endl << endl;
  34.345 +
  34.346 +    // 1. create identity
  34.347 +    const char* bella_address = "pep.test.bella@peptest.ch";
  34.348 +    const char* bella_fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  34.349 +    const char* bella_userid = "TOFU_pep.test.bella@peptest.ch"; // simulate temp ID
  34.350 +    const char* bella_username = "Annabella the Great";
  34.351 +    const string bella_pub_key = slurp("test_keys/pub/pep.test.bella-0xAF516AAE_pub.asc");
  34.352 +    
  34.353 +    statuspub = import_key(session, bella_pub_key.c_str(), bella_pub_key.length(), NULL);
  34.354 +    assert(statuspub == PEP_STATUS_OK);
  34.355 +
  34.356 +    pEp_identity* bella = new_identity(bella_address, bella_fpr, bella_userid, bella_username);
  34.357 +    
  34.358 +    // 2. set identity
  34.359 +    status = set_identity(session, bella);
  34.360 +    assert(status == PEP_STATUS_OK);
  34.361 +    free_identity(bella);
  34.362 +    
  34.363 +    const char* not_my_userid = "Bad Company";
  34.364 +            
  34.365 +    bella = new_identity(bella_address, NULL, not_my_userid, bella_username); 
  34.366 +    status = update_identity(session, bella);
  34.367 +    assert(status == PEP_STATUS_OK);
  34.368 +    assert(bella->fpr);
  34.369 +    assert(strcmp(bella->fpr, bella_fpr) == 0);
  34.370 +    assert(bella->username);
  34.371 +    assert(strcmp(bella->username, bella_username) == 0);
  34.372 +    assert(bella->user_id);
  34.373 +    assert(strcmp(bella->user_id, not_my_userid) == 0); // ???
  34.374 +    assert(!bella->me); 
  34.375 +    assert(bella->comm_type == PEP_ct_OpenPGP_unconfirmed);
  34.376 +    assert(strcmp(bella->address, bella_address) == 0);
  34.377 +
  34.378 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address and username; temp user_id in DB patched" << endl << endl;
  34.379 +    free_identity(bella);
  34.380 +
  34.381 +    cout << "****************************************************************************************" << endl;
  34.382 +    cout << "* II: 9. update_identity() for address, username, and user_id, but no matching record" << endl;
  34.383 +    cout << "****************************************************************************************" << endl << endl;
  34.384 +    
  34.385 +    const char* rando_name = "Pickley BoofBoof";
  34.386 +    const char* rando_userid = "Boofy";
  34.387 +    const char* rando_address = "boof@pickles.org";
  34.388 +    somebody = new_identity(rando_address, NULL, rando_userid, rando_name);
  34.389 +    status = update_identity(session, somebody);
  34.390 +
  34.391 +    assert(status == PEP_STATUS_OK);
  34.392 +    assert(!somebody->fpr || somebody->fpr[0] == '\0');
  34.393 +    assert(somebody->username);
  34.394 +    assert(strcmp(somebody->username, rando_name) == 0);
  34.395 +    assert(somebody->user_id);
  34.396 +    assert(strcmp(somebody->user_id, rando_userid) == 0); // ???
  34.397 +    assert(!somebody->me); 
  34.398 +    assert(somebody->comm_type == PEP_ct_key_not_found);
  34.399 +    assert(strcmp(somebody->address, rando_address) == 0);
  34.400 +
  34.401 +    cout << "PASS: update_identity() correctly created record with no key" << endl << endl;
  34.402 +    free_identity(somebody);
  34.403 +    
  34.404 +    cout << "****************************************************************************************" << endl;
  34.405 +    cout << "* II: 10. update_identity() for address, username, but no matching record" << endl;
  34.406 +    cout << "****************************************************************************************" << endl << endl;
  34.407 +
  34.408 +    const char* rando2_name = "Pickles BoofyBoof";
  34.409 +    const char* rando2_address = "boof2@pickles.org";
  34.410 +    somebody = new_identity(rando2_address, NULL, NULL, rando2_name);
  34.411 +    status = update_identity(session, somebody);
  34.412 +    const char* expected_rando2_userid = "TOFU_boof2@pickles.org";
  34.413 +
  34.414 +    assert(status == PEP_STATUS_OK);
  34.415 +    assert(!somebody->fpr || somebody->fpr[0] == '\0');
  34.416 +    assert(somebody->username);
  34.417 +    assert(strcmp(somebody->username, rando2_name) == 0);
  34.418 +    assert(somebody->user_id);
  34.419 +    assert(strcmp(somebody->user_id, expected_rando2_userid) == 0); // ???
  34.420 +    assert(!somebody->me); 
  34.421 +    assert(somebody->comm_type == PEP_ct_key_not_found);
  34.422 +    assert(strcmp(somebody->address, rando2_address) == 0);
  34.423 +
  34.424 +    cout << "PASS: update_identity() correctly created record with no key" << endl << endl;
  34.425 +    free_identity(somebody);
  34.426 +
  34.427 +    cout << "****************************************************************************************" << endl;
  34.428 +    cout << "* II: 11. update_identity() for address only, but multiple matching records" << endl;
  34.429 +    cout << "****************************************************************************************" << endl << endl;
  34.430 +
  34.431 +    const char* bella_id_2 = "Bella2";
  34.432 +    bella = new_identity(bella_address, NULL, bella_id_2, bella_username);
  34.433 +    
  34.434 +    // 2. set identity
  34.435 +    status = set_identity(session, bella);
  34.436 +    assert(status == PEP_STATUS_OK);
  34.437 +    free_identity(bella);
  34.438 +                
  34.439 +    bella = new_identity(bella_address, NULL, NULL, NULL); 
  34.440 +    status = update_identity(session, bella);
  34.441 +    assert(status != PEP_STATUS_OK);
  34.442 +
  34.443 +    cout << "PASS: update_identity() correctly failed with no matching records (too little info)" << endl << endl;
  34.444 +    
  34.445 +    cout << "****************************************************************************************" << endl;
  34.446 +    cout << "* III: key election " << endl;
  34.447 +    cout << "****************************************************************************************" << endl << endl;
  34.448 +
  34.449 +    cout << "****************************************************************************************" << endl;
  34.450 +    cout << "* III: 1. key election: get identity for user with expired key" << endl;
  34.451 +    cout << "****************************************************************************************" << endl << endl;
  34.452 +
  34.453 +    // 1. create identity
  34.454 +    const char* bernd_address = "bernd.das.brot@darthmama.org";
  34.455 +    const char* bernd_fpr = "F8CE0F7E24EB190A2FCBFD38D4B088A7CAFAA422";
  34.456 +    const char* bernd_userid = "BERND_ID"; // simulate temp ID
  34.457 +    const char* bernd_username = "Bernd das Brot der Ultimative Testkandidat";
  34.458 +    const string bernd_pub_key = slurp("test_keys/pub/bernd.das.brot-0xCAFAA422_pub.asc");
  34.459 +    
  34.460 +    statuspub = import_key(session, bernd_pub_key.c_str(), bernd_pub_key.length(), NULL);
  34.461 +    assert(statuspub == PEP_STATUS_OK);
  34.462 +
  34.463 +    pEp_identity* bernd = new_identity(bernd_address, bernd_fpr, bernd_userid, bernd_username);
  34.464 +    
  34.465 +    // 2. set identity
  34.466 +    status = set_identity(session, bernd);
  34.467 +    assert(status == PEP_STATUS_OK);
  34.468 +    free_identity(bernd);
  34.469 +                
  34.470 +    bernd = new_identity(bernd_address, NULL, bernd_userid, bernd_username); 
  34.471 +    status = update_identity(session, bernd);
  34.472 +    assert(status != PEP_STATUS_OK);
  34.473 +    assert(!bernd->fpr || bernd->fpr[0] == '\0');
  34.474 +    assert(bernd->username);
  34.475 +    assert(strcmp(bernd->username, bernd_username) == 0);
  34.476 +    assert(bernd->user_id);
  34.477 +    assert(strcmp(bernd->user_id, bernd_userid) == 0); // ???
  34.478 +    assert(!bernd->me); 
  34.479 +    assert(bernd->comm_type == PEP_ct_key_expired);
  34.480 +    assert(strcmp(bernd->address, bernd_address) == 0);
  34.481 +
  34.482 +    cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_expired" << endl << endl;
  34.483 +    free_identity(bernd);
  34.484 +
  34.485 +
  34.486 +    cout << "****************************************************************************************" << endl;
  34.487 +    cout << "* III: 2. key election: get identity for user with only revoked keys " << endl;
  34.488 +    cout << "****************************************************************************************" << endl << endl;
  34.489 +    
  34.490 +    status = revoke_key(session, new_fpr, "Because it's more fun to revoke ALL of someone's keys");
  34.491 +    assert (status == PEP_STATUS_OK);
  34.492 +    
  34.493 +    new_me = new_identity(uniqname, NULL, NULL, NULL);
  34.494 +    
  34.495 +    status = update_identity(session, new_me);
  34.496 +    assert(status != PEP_STATUS_OK);
  34.497 +    assert(!new_me->fpr);
  34.498 +    assert(new_me->username);
  34.499 +    assert(strcmp(new_me->username, start_username) == 0);
  34.500 +    assert(new_me->user_id);
  34.501 +    assert(strcmp(new_me->user_id, default_own_id) == 0);
  34.502 +    assert(new_me->me);
  34.503 +    assert(new_me->comm_type == PEP_ct_key_revoked);
  34.504 +    
  34.505 +    cout << "PASS: update_identity() correctly rejected two revoked keys with PEP_KEY_UNSUITABLE and PEP_ct_key_revoked";
  34.506 +    cout << endl << endl;
  34.507 +
  34.508 +    free_identity(new_me);
  34.509 +
  34.510 +    cout << "****************************************************************************************" << endl;
  34.511 +    cout << "* III: 100000000. key election: more to come " << endl;
  34.512 +    cout << "****************************************************************************************" << endl << endl;
  34.513 +
  34.514 +    return 0;
  34.515 +}
    35.1 --- a/test/pEp_subject_received_test.cc	Mon Jan 15 12:26:14 2018 +0100
    35.2 +++ b/test/pEp_subject_received_test.cc	Mon Jan 29 12:15:51 2018 +0100
    35.3 @@ -34,10 +34,12 @@
    35.4      PEP_STATUS statuskey3 = import_key(session, keytextkey3.c_str(), keytextkey3.length(), NULL);
    35.5  
    35.6      pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", "93D19F24AD6F4C4BA9134AAF84D9217908DB0AEE", PEP_OWN_USERID, "pEp Test Recipient");    
    35.7 +    me->me = true;
    35.8      PEP_STATUS status = myself(session, me);
    35.9      
   35.10      pEp_identity * you = new_identity("pep.test.alice@pep-project.org", NULL, "TOFU_pep.test.alice@pep-project.org", "Alice Test");    
   35.11 -    
   35.12 +    you->me = false;
   35.13 +
   35.14      status = update_identity(session, you);
   35.15      trust_personal_key(session, you);
   35.16      status = update_identity(session, you);
    36.1 --- a/test/revoke_regen_attach_test.cc	Mon Jan 15 12:26:14 2018 +0100
    36.2 +++ b/test/revoke_regen_attach_test.cc	Mon Jan 29 12:15:51 2018 +0100
    36.3 @@ -45,10 +45,19 @@
    36.4      key_mistrusted(session, me);
    36.5  
    36.6      cout << "re-generated fingerprint \n";
    36.7 +    free(me->fpr);
    36.8 +    status = myself(session, me);
    36.9 +    assert(status == PEP_STATUS_OK);
   36.10      cout << me->fpr << "\n";
   36.11      
   36.12 -    assert(strcmp(me->fpr, prev_fpr));
   36.13 -
   36.14 +    assert(me->fpr);
   36.15 +    assert(strcmp(me->fpr, prev_fpr) != 0);
   36.16 +    cout << "New fpr is: " << me->fpr;
   36.17 +    
   36.18 +    me->fpr = NULL;
   36.19 +    me->comm_type = PEP_ct_unknown;
   36.20 +    myself(session, me);
   36.21 +    
   36.22      identity_list *to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, "42", "pEp Test Alice (test key don't use)"));
   36.23      message *msg = new_message(PEP_dir_outgoing);
   36.24      assert(msg);
   36.25 @@ -65,12 +74,14 @@
   36.26      assert(enc_msg);
   36.27      cout << "message encrypted.\n";
   36.28  
   36.29 -    cout << msg->attachments->filename;
   36.30 -    assert(bloblist_length(msg->attachments) == 2);
   36.31 -    assert(strcmp(msg->attachments->filename, "file://pEpkey.asc") == 0);
   36.32 -    assert(strcmp(msg->attachments->next->filename, "file://pEpkey.asc") == 0);
   36.33 -
   36.34 -    cout << "message contains 2 key attachments.\n";
   36.35 +    // cout << msg->attachments->filename;
   36.36 +    // int bl_len = bloblist_length(msg->attachments);
   36.37 +    // cout << "Message contains " << bloblist_length(msg->attachments) << " attachments." << endl;
   36.38 +    // assert(bloblist_length(msg->attachments) == 2);
   36.39 +    // assert(strcmp(msg->attachments->filename, "file://pEpkey.asc") == 0);
   36.40 +    // assert(strcmp(msg->attachments->next->filename, "file://pEpkey.asc") == 0);
   36.41 +    // 
   36.42 +    // cout << "message contains 2 key attachments.\n";
   36.43  
   36.44      free_message(msg);
   36.45      free_message(enc_msg);
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/test/test_keys/priv/bernd.das.brot-0xCAFAA422_priv.asc	Mon Jan 29 12:15:51 2018 +0100
    37.3 @@ -0,0 +1,59 @@
    37.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    37.5 +
    37.6 +lQOYBFpctn4BCACx7hSdsA+AnAQ+VRT8vb820MUhgiZ2gBOmmjZt+R+U8jGA0RFT
    37.7 +OFGWMNwVNNDV+FFES4yTbbmH3JPEPfRTKzcBJrty0WfTrCQ65lv1GBmGPO306pg3
    37.8 +/AA8n8e7SAVwc3fHB0oImQTkiN9Jx13KvFhSm32e4DWlDEYEIOSXY5ZjmczMoLTq
    37.9 +mwbf0ROXI+aXh793AS+oUlxl8CZJxwW8EmLiHAc2KJVXubJCq3nkwtz03/NvgCYL
   37.10 +M0cXds/jNrEEpTbXjx7pnVJC1tIrCrFrKChM4qUpcWqSPwn0pIs8EP2FHS5Ou0MK
   37.11 +O59bGVWP5EPy2gyS8bfgtWt8tL0jilBlUa4hABEBAAEAB/wM0c7+x4BubznntctD
   37.12 +zyCs6zYbd8bxUxassmqz2gxPonLfnvCPyDx/ROOZIYuJsbuaiejwdv+JjY0V9Agb
   37.13 +n+mgIHFxUIDEYaA19YKa8j1l4b5GnvUQVOHoJvObMjwLbJOs2CvE2nrdmQuhbgb7
   37.14 +bujcLCN3uXFpWVeIFPNIrF5ZrEx8g+Znv7pR1p9LeLaLoizn1GB/DBnU2xQvLKY1
   37.15 +2MRyl3yd/vFwynVtcKVcpmt0sZpBJaZx335OWfE27vOEK18iGWYzEXCupZPCCCKC
   37.16 +kUQxu6Rm0cieT/0XuFNpG8hsszHzb3s2Am4S75cxhhW8zCINTvFGiWdKVIdlKT3O
   37.17 +hHI7BADKk3ElgtyoSlnvS3Cz/f+Rmm65bHcTcWplHsls2bEgRKZ9Zeb1nHxcTRqN
   37.18 +U/9mPrnCpjNwVTEsXORiiSrnpn0gyNloDMtmbM2CtI/+71/2xhb+nfQ3C07C83dz
   37.19 +ynas82Cz9iMHJfGR/W/AYplM65UQ8wfV4n/eWm6r54UCM+bFgwQA4Nq2DD+EWrjM
   37.20 +qSEhe0jvxCPCwod5UqTm2olTq/Wnrh/cnDGZKyUQ67ywdijFQ+L963UUdJrk+Ldu
   37.21 +ms9MN12xWrJguSQ0x62c9uUKgOROEPXwSM6d5aPpToLiRB8aMOF9qQToE9XjIJDQ
   37.22 +yHfjaCXdDK3IwtsfH8tPxyM+25Mu0IsD/3a8z62/0w7yg/YUj/52zJWvM5MnBYl6
   37.23 +E3rSMclcNXBJPvgQAGXtxYyAYC2VBfNclm7f0tqv4nWDx+x43BL4vDgh9lwHh3eN
   37.24 +1vbhrAhp3U/RNo928LmwsD03n8XQ1rY7b6ixYJ0LbzgVJND39eLinzi2IaWzRAED
   37.25 +8nq6V3ua/yv3VS+0ckJlcm5kIGRhcyBCcm90IGRlciBVbHRpbWF0aXZlIFRlc3Rr
   37.26 +YW5kaWRhdCAoSW50ZW50aW9uYWxseSBFeHBpcmVkIEtleSBmb3IgVGVzdGluZyEp
   37.27 +IDxiZXJuZC5kYXMuYnJvdEBkYXJ0aG1hbWEub3JnPokBVAQTAQgAPhYhBPjOD34k
   37.28 +6xkKL8v9ONSwiKfK+qQiBQJaXLZ+AhsDBQkAAVGABQsJCAcCBhUICQoLAgQWAgMB
   37.29 +Ah4BAheAAAoJENSwiKfK+qQi+OMIAIXUeU2A74JwnbtO7XzGZ60j7roCAOAn5AHx
   37.30 +GNnWlguRIk0it+7H1PPdFMETWDKATVesmNFVATQ1vs5/G3TmHCzie/yjLMKHg2iv
   37.31 +ouQhEde5x5sbI+w501GDinDLihJC1kIrBW9MnEE4LniXZ1SBXoTwy9H7vLhvgckH
   37.32 +p3JL/zT3Z7hn/oGT21Der/smYJp8lI3gLOA52eFCiwtzn1Rv09fjUYIcuvHFMl9o
   37.33 +1yJTu/hLSRBwJliLdvl/HQLiM+onr7NoJCxdnvDrQUqMVH4qjDAHJKZMjjy5TLko
   37.34 +TAcLeohO3NlMSXmRIhDUIr6S34hUNdrHIopORgajXbfKbM4iAL6dA5gEWly2fgEI
   37.35 +AKnO1DQBmoB4KlrcNKXlCazCWp0cLPWB11cIGpb0DGeVEndCxQfBGRocZs7zZn1M
   37.36 +pEpzRx9Ae/R/o3w42IaBF62RXOpofq2WSe/TYI4QJJvSPJ168VuP9BmNeARL0Q1E
   37.37 +AMro483LCCUpGIOb7uC9hn/Bi1OmK956tJqEOSYqrpxkY3kw3CUVknDCd12nc7zB
   37.38 ++1KQDCYSqQVZJ5zkagr65E26SXfvzf3n/x+UB9FhnIE2zzkUJvsgY7s7z/XL/NXD
   37.39 +uKjPbbIL6bhhP08koljCN49q0pSlB+Evw5oukmON46JSe1YymBzVA49b73IrSVrX
   37.40 +KT0tbKVguiUG3ewc9aunUpcAEQEAAQAH/jIgkucZVBU5o/M3jzkr0DvWEe7QOvts
   37.41 +jXetNkA6ohDP4mgfZ0+fMrxRBw5vruEtR1CNEEFLBWyLY2UP2Od341gDEeVG3KJ8
   37.42 +u63W/eliHZR8LxWkDezkJYCHkRbflMJwQTWlI16EYY6qv4hWd2GTwUkkhu82Hjwq
   37.43 +h/cXMlGwhuQ2iTDJOcCmYh3ExgVrhc6XPCmtPSuG28KR2sN2pRDl5pPH+/wbKNVS
   37.44 +hk01m9/kDdDMSi6U4PMPZ4Sq/0mzlfWXeD6Itn2vKhLnEFp3vYr8P8m2+AgWtM+D
   37.45 +7fPAf1O07xNWxDkNgnolgluoU3FrpifYwaaj6N6rFGsBEv0Nfwju8kEEAMiu71QB
   37.46 +kLf6Mf1R/lRWEyP6/HPiNu9fMHnV+ml6VFyiaJCCZvUBbZOKDOmedVS3pJXGp9uk
   37.47 +G6CLSqlCghgPK9M+ExtSN2JrgNPU1bXSMviHVMq70HtUeo/wHPfIoYpQ+VRiu5i8
   37.48 +kZgkCCFCKlxr0WTp3tI51xu0g0fQOrpT16hXBADYnTG7WYMHyDCO3uh+/zErhw/r
   37.49 +6POZZWegnPteim6GN8X8NG7GJnQB7Voqn8X7tAcKPgCQBEdOltz3PWWDm66E4VFs
   37.50 +e7Bau5i+SshzKXdKwYVkGH6h8YWlJjqOm3m9WCAUg517xy9VMyxihpTvZs2Wwtk2
   37.51 +TY2/Cv7RyrXAAvw/wQP/XQjphddiuST6wKiAWsbzYhuof3zyXX3fy4vE6rNxvl/D
   37.52 +RAOcKFex0Q59K0YOePRYrEjQlUoPhqyeQGUp7DZsyiTGMpmFVRqg6LcmAfQdO62y
   37.53 +53gEc5cr5fnZOKavu5agP/ktry28z8pzg0pXUkqcdqxluIXp9Av/Dc+aB5VzQXtG
   37.54 +k4kBPAQYAQgAJhYhBPjOD34k6xkKL8v9ONSwiKfK+qQiBQJaXLZ+AhsMBQkAAVGA
   37.55 +AAoJENSwiKfK+qQifC4H/13K4LnWFOqSAXzzqnass2aY++1EVXRnMDdXsp3jU17t
   37.56 +CFJZufoNAw7vmInrCgxMViUjfV6DfyDsrYynDWfIAS6FO3ThnFtgkgekdTrNg6DZ
   37.57 +OMl7D9+xaP0S/fVITZz5XRqs7amRkojftQHJMpPNoXwcGK1hGLgPIvN4cbLIRvnG
   37.58 +SDhkstFdsvNbC92z2upit7+yq9eW+Kn2exJRszgbZ53ghmhNy4CrhjJC90CsYF1S
   37.59 +zsDlqwc1ET4vjV1pCnjyVk+pNsw1V9kKMm8icFFwB57xX5Q9EdwMipNaWWg7CHMM
   37.60 +8+Bjqsj2qHs0LNWO7eQyr8Uj0BwfT04Wwz68iD57lEQ=
   37.61 +=GIbJ
   37.62 +-----END PGP PRIVATE KEY BLOCK-----
    38.1 --- a/test/test_keys/priv/pep-test-recip-0x08DB0AEE_priv.asc	Mon Jan 15 12:26:14 2018 +0100
    38.2 +++ b/test/test_keys/priv/pep-test-recip-0x08DB0AEE_priv.asc	Mon Jan 29 12:15:51 2018 +0100
    38.3 @@ -21,38 +21,1478 @@
    38.4  W5pPkaJqREs2JRmWh9FtglhnqzjfZwW9KaMcYgORPvK4pXMD1gHNewJl9LHvKLIr
    38.5  g1MlsNmpcOUhNKS0Z3BFcCBUZXN0IFJlY2lwaWVudCAoS2V5cGFpciBmb3IgS3Jp
    38.6  c3RhIHRlc3RzIC0gbm90IHNlY3JldCBpbiBhbnl3YXkhISEhKSA8cGVwLnRlc3Qu
    38.7 -cmVjaXBAa2dyb3Rob2ZmLm9yZz6JAT8EEwEIACkFAlh711YCGwMFCQHhM4AHCwkI
    38.8 -BwMCAQYVCAIJCgsEFgIDAQIeAQIXgAAKCRCE2SF5CNsK7p1nCACNWH+sADtb9OKO
    38.9 -oiZX3JXbO66D7YaCsuIJfh1ZtViessDl6uuCKULkyZOhRGkMMwrlMetfSz4/N6Hx
   38.10 -iPPNKfdDnJnP0gX45KOsVKB34VdgvYN4kUKL4hvAAxfJC5nI+JXuOwUbxs6FRYkQ
   38.11 -rYYv1I+qufdaCzAWc9KLeyBpp7uYNBHOOELrWxvAFMDPMBSioCwGYU04cJsBLXQC
   38.12 -bsxdyFiZSgAS1A/oIEQ87fZtPYuq6SHrZB2/bsDiEIFKDmK91zY6phZtgzVi77pC
   38.13 -K6YL/GZBi5ZSBXuzVFMjeVwJr3ajsVDs78FCmKT+lcmAvZleEhMKpovs1Ng7H1v3
   38.14 -EQU2jhOpnQOYBFh711YBCADZlca5RzMLUOX42+krKFcK9KGjanackuKlU0DbDh/F
   38.15 -8x3ouVDV3+Nu4Ti6/fxtnuaSW7ZmssOTYGJKaGqRjpNwe6HjY1giMr5KO2J8TsOJ
   38.16 -aKhPyrgCzgeX+a4nAIE8P8CeEiYOEG10wyZ1i3PH+JdeAmDR2/YoRAB5XXaKAR+z
   38.17 -1Aa1i+tgdw+nyZSN9hFvOjruyoMdvkcEo94x3Ylw4fVkzTl5zlyss3CgRzJa9EW0
   38.18 -BnpH2OVTi6S39o/YzUidWzysu2I2/DhUcGuWDoDOXD1ILULhUIC4UF12t0coBtRP
   38.19 -IG4MoKya5UkiVK0j6q2PD0yj5EJkvyn77NSAHM4Fih3NABEBAAEAB/wJIOEA9e08
   38.20 -zMyRJ7y9DEi2k3PSlM1cHUd38ym15v5LQjtff6LWDjoO9VD5e11jRfbbbhCVd2uA
   38.21 -G9uTzpSl/arO3cj5broMWT+lgp9LosxOT/87tcAJkhY8eIOnbDx/yBbvKsjA70yA
   38.22 -SQ2sgci+O34yOfxQ4Z8Oqmewr8yg1pI7a5Zz54oB/6y+VBjqPXSbW3V1Kb99xEfD
   38.23 -E5XWxPag8uPn1anExmvU4IfIlzNOpUMcfYbevhVOkhpFxwXtsh95SeGRDKwsniUa
   38.24 -Jq4XashfRq75HueUJnDV73zkPc0YZYUMzybKlF0+tOT49dIBJR4wk7JXDePF59nu
   38.25 -GpvnXL6FtoEBBADebS+XVp3g5QSsctyBoH4sA7C5RSlHUf2kKILRF7DYdyJMgEji
   38.26 -iD3BM++PPnW2Gime43je8LDJOsqKCncMw/sn9Lpdyz1JJkNlgF3PGVHzomrSafNv
   38.27 -9gv8SqbGI8niiWVZH34NAr7XrRUUZE0Ggzc7ehiyOjWRG87ees0w45enTQQA+m2C
   38.28 -7f0fRTMScVyo6l9TMITZY9hS76Zre8jBhUl0cYrftU1M/04vU8s4gIk85WBbE+Ir
   38.29 -Cr91hiqyi1lLpndAz2gMct3F8YbtjFZRmqhTZpNh0kVc4WzPf7Ctu1SIac3nz4oZ
   38.30 -v3ooDk/Ks/xbd9526q+1mxQuFmOU59MQxtlSEIEEAKJgb1Ri6oFPn4dSJUYv1HuV
   38.31 -nUgkmnJtrf7jDOPPu2PmPSiWu8/QGzmHwbjO2erV2Wa46wlJ9GYifCzo545d92Yl
   38.32 -IkpNok7Btkz9AQjkJ/QKPgA/0K5cKVpSnIF16fcddSK3uc2rG5fRypfVbONvQ17f
   38.33 -VrU8gWYvCLZE91X5tXM3SoGJASUEGAEIAA8FAlh711YCGwwFCQHhM4AACgkQhNkh
   38.34 -eQjbCu6LMgf/Vbtpj0Y3swMYWDahLZjjPKPzvaBnLHnmlZJS0culFItLbWTZB7Wu
   38.35 -Hn/pv1pXsKF4XNnl/zK8HPEEJiVuA2eWGsA9XgqBGYCwYs8zhJFkeQ55iGGuMhGy
   38.36 -PT3ie153vqjbDXGC7ajlksEwP3ESrkLjIuHWov8karzIXKiz4M9qnrJY6OmNfO79
   38.37 -qxigEs5BuIZNWS/Dy1de5RAfQgSVvD3uXX5cLUAO/FxKfHVoHdL7JEcrJGf91T+u
   38.38 -c9LDOtccvZRAZt/l3M7qRNudRF3HnvunsfNMi1xLzz340lVKO564mYT38yAX9zhk
   38.39 -fkPQwHlDzt8ruC4IUKQljSKCwngrpl+qyQ==
   38.40 -=V/XN
   38.41 +cmVjaXBAa2dyb3Rob2ZmLm9yZz6JAVAEEwEIADoCGwMHCwkIBwMCAQYVCAIJCgsE
   38.42 +FgIDAQIeAQIXgBYhBJPRnyStb0xLqRNKr4TZIXkI2wruBQJaXUQHAAoJEITZIXkI
   38.43 +2wru1+UH/RIteVXEUBqyJ1S68hn5yGNiR/3OX012TuqU4HB1mt4w+mKCUVwEInxX
   38.44 +ivpWqQbkWRNoI6vkf7cXHEPiFOdjuek4DPo7D7KOXcXWvttMz+S+HPXZk5PerDGx
   38.45 +z8bruvfbbi63YGqgRrBIcdfX8jIe5GmEd3VVxjZKEDr0/czwWn40W3RAEm2EZfg/
   38.46 +RnxxHaW3TBURwJlkRGA0IrpP5OibI8jxpx5OgrFeZbbFw0IkNANiO57XNNmH1CL/
   38.47 +ggYZwvC4h8WX/b0w3D1r020jgo+M/VS3DfeSn/fMzV5n/a6A06poARmPFOsQN3qy
   38.48 +/4hf0EbA52aEJq1ucqbXtlpsuDeVX5ydA5gEWHvXVgEIANmVxrlHMwtQ5fjb6Sso
   38.49 +Vwr0oaNqdpyS4qVTQNsOH8XzHei5UNXf427hOLr9/G2e5pJbtmayw5NgYkpoapGO
   38.50 +k3B7oeNjWCIyvko7YnxOw4loqE/KuALOB5f5ricAgTw/wJ4SJg4QbXTDJnWLc8f4
   38.51 +l14CYNHb9ihEAHlddooBH7PUBrWL62B3D6fJlI32EW86Ou7Kgx2+RwSj3jHdiXDh
   38.52 +9WTNOXnOXKyzcKBHMlr0RbQGekfY5VOLpLf2j9jNSJ1bPKy7Yjb8OFRwa5YOgM5c
   38.53 +PUgtQuFQgLhQXXa3RygG1E8gbgygrJrlSSJUrSPqrY8PTKPkQmS/Kfvs1IAczgWK
   38.54 +Hc0AEQEAAQAH/Akg4QD17TzMzJEnvL0MSLaTc9KUzVwdR3fzKbXm/ktCO19/otYO
   38.55 +Og71UPl7XWNF9ttuEJV3a4Ab25POlKX9qs7dyPluugxZP6WCn0uizE5P/zu1wAmS
   38.56 +Fjx4g6dsPH/IFu8qyMDvTIBJDayByL47fjI5/FDhnw6qZ7CvzKDWkjtrlnPnigH/
   38.57 +rL5UGOo9dJtbdXUpv33ER8MTldbE9qDy4+fVqcTGa9Tgh8iXM06lQxx9ht6+FU6S
   38.58 +GkXHBe2yH3lJ4ZEMrCyeJRomrhdqyF9Grvke55QmcNXvfOQ9zRhlhQzPJsqUXT60
   38.59 +5Pj10gElHjCTslcN48Xn2e4am+dcvoW2gQEEAN5tL5dWneDlBKxy3IGgfiwDsLlF
   38.60 +KUdR/aQogtEXsNh3IkyASOKIPcEz748+dbYaKZ7jeN7wsMk6yooKdwzD+yf0ul3L
   38.61 +PUkmQ2WAXc8ZUfOiatJp82/2C/xKpsYjyeKJZVkffg0CvtetFRRkTQaDNzt6GLI6
   38.62 +NZEbzt56zTDjl6dNBAD6bYLt/R9FMxJxXKjqX1MwhNlj2FLvpmt7yMGFSXRxit+1
   38.63 +TUz/Ti9TyziAiTzlYFsT4isKv3WGKrKLWUumd0DPaAxy3cXxhu2MVlGaqFNmk2HS
   38.64 +RVzhbM9/sK27VIhpzefPihm/eigOT8qz/Ft33nbqr7WbFC4WY5Tn0xDG2VIQgQQA
   38.65 +omBvVGLqgU+fh1IlRi/Ue5WdSCSacm2t/uMM48+7Y+Y9KJa7z9AbOYfBuM7Z6tXZ
   38.66 +ZrjrCUn0ZiJ8LOjnjl33ZiUiSk2iTsG2TP0BCOQn9Ao+AD/QrlwpWlKcgXXp9x11
   38.67 +Ire5zasbl9HKl9Vs429DXt9WtTyBZi8ItkT3Vfm1czdKgYkBNgQYAQgAIAIbDBYh
   38.68 +BJPRnyStb0xLqRNKr4TZIXkI2wruBQJaXUQTAAoJEITZIXkI2wru7mcH/iE6LKxN
   38.69 +Sgd92tsVXyAz4hAJMgWd4yrRlNyUCeeKFJVEvQAdu8ysazd6atlGNdf0hLAJs7Ln
   38.70 +zE5NQBwLdfJixMMm2vb6+EKN+hGYYJJL2GW24CVGCkc895yykdPDtaV0PIRS878P
   38.71 +5mSEhuZNlw9SDZotb3ipQRfX04jozScsYPxxXYtJrz72ghE2NosU3M/pEHMzTBfb
   38.72 ++KJ9wUmQciL+c7RVpvCTGb9QomdZpuLZEOAqLdbUZ10YggXvLI2xse+JitlG6uB6
   38.73 +Ieq3dGLNITOgc1pKmo4WI3rsY/FuHhuYfT7g68svEiwzmTwzeKAJmFvQ5LWWWTHx
   38.74 +5IemibOQ9C5dgXeVA5gEWl0mOwEIAMntRnGKBZZFyvx0WmbrUoHpAktcH/RN+AAx
   38.75 +EOixLZB+zrWW3owCzEoM+2dhxPXMfJCn/N/DI3r6P0DPWbXfUhtcqW70YMEUAoVV
   38.76 +sYKAc1nABMid+v7uxtL7xmuKwUzYhGBl2NQ+/cgvFN8dB8lhy9DOnYT9p5ZUy+Dh
   38.77 +dHb8261/MWOr/sW0oy+xzFncvnDkBKKQUkzW6zn9vXTtCPKtgq70IOzwmfohAHcH
   38.78 +UZpLOU71cQeRmaOIC6tfHGprUMWFE6oFLrdKwOcy66IwiH/s7zOEWfCtlV8YYaA1
   38.79 +4BzmfNbE+w4Eb0WAsvYwnFlMPNSL6En33Xuj9oT/fqNTzd/o+6kAEQEAAQAH/jto
   38.80 +9jrdkvs9mZVhXl+9iM70EVq+xiAI+JiF1yW/S1qiFItU0jF7eUOoQieOmnZ/LX8a
   38.81 +DcqADWZXTljxKMHb7LpkLu2YNQdZrcwxBEMTK90SI9YqtPhgpFra/OwTLQBBC+GY
   38.82 +1YzM47oMMCXc0rercF4FDE9emfofBMUrUCraBoAqz93/ntZFeeQGq9mGdDA8R51x
   38.83 +1nXE/wFI7EppGhDiLxnKYpFx47+eUXn/d4HG+qjDpont6IkNk2Rjr8aC7T4fJsHl
   38.84 +N5yrnZDOYcV1gS9putksdV3ctLQVOtuNw2EnfAh5St2mJJIT+ujcA+VQaNtVwnwy
   38.85 +r3hmY1q6FJeZs0MAmMkEANKxbJsGGSsxcqpXkw0j+aMTo3HhT+5vveMzIFeRceDS
   38.86 +SxDKpnUZzeRiloQXLHlaCxUeZ4YZOjf8zy/rSGcr4VaAzHHY4QjR2p7i/e/5BJkp
   38.87 +9hsl9vKPq1vKp14hnUAtabxQxA7OD+45BgJVi9M1om6T3jrEe6r96846HY51sGOj
   38.88 +BAD1WUZBfwaOTfO5JcJNIeSe+sq6/DJaGC8n/L4b28yqmSs47AkFBNWhiEetqIb3
   38.89 +MN5dv6EOKeoIp/ZxmwIK9rQcUGNV8ylMN+r/t8yEOmU9OX5VLAe43ZRjh79TqRee
   38.90 +pMWL6sbkiiBuiTB8hdvJZtmSighhYUk5bhkJDM170HP4QwP+O2Z1/qDb2t5o2rQl
   38.91 +P/SbSEMWnBNcJIi1Pf0cEcNTRa37OFXnheliW+I8ap///a6fjJAPenAjd0RK5+dF
   38.92 +Eur0kbx5hv+d8T2KJe9QhdZRllaqqOU4+9ndfPXmNf/Xb1LPVg+h67U/FfXFYiZM
   38.93 +qLE6dVGkcQ0YXfEdvemPSFvG6SREs7QxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAu
   38.94 +dGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBEQtvu2faUNx9r+0
   38.95 +F0BCeJwpy2+1BQJaXSY9AhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheA
   38.96 +AAoJEEBCeJwpy2+1/5UH/2nufLMaHMjRF9is4m1B7wvdJAooemvwmVIXBgjumEVL
   38.97 +A/oYT1whKThiZEi8FTMaQB3zKpnCOV8hve/xnFH/zNI+RgIYZrtrVQT8jxkKGfC6
   38.98 +u3gUBiq6A1QEhB3+HJ5/Vnxr9ZMzKNyqq16nUkX48eekyLMl739Wyy8l/bnqJlUZ
   38.99 +V1YiKgptEs0K8iqRNpjWmYL0Va/l/X8CCzf13eMu1cY+JeDcEDrglmM8vqiHGs/Y
  38.100 +/6aJJySk71YB2drr279AuH+JYUCmO6EntJX/5bZktOzH8FN3KS+GTnHupMzDTIsQ
  38.101 +spepadZfylKJkXTvxJ5lqNbM7RSmt4VgPIubWkLoNECdA5gEWl0mPQEIAN2cbAy0
  38.102 +9RNMf7o4Slpmc4SVoT/b0ywdvF8u+EISDJTM9Azg13j7q0dl20+JgIOfyKKqoea6
  38.103 +MwDtBtVRbAMWQjxtrs0S1eWM04u+9vPbxragoIFKPFpTWvtqVCQCzOPbja9ECRHV
  38.104 +SpXNAj8tEz+344LSzTRDpwh2KL5FKClyRgO7bFAIum9Z1EZVuVXL3oYhJ5emLyBb
  38.105 +VVhVonW6Rxltx/KiCk0qGn36AdnQXdrdtrcrVuFJSLht7+VuWwK2/2a18jBbNsjx
  38.106 +4p3oMGX4V3G36wfBf1gPAv4e8jhN6d2jDN/O/HsPoDaVrBwHHf/0mM7bJR37RUgx
  38.107 +wTITba8ahqLU9nUAEQEAAQAH/A3WQnjYo6S81gzOjvXuB7Bzl0nhc+IBSU24JRAb
  38.108 +CGYSFfrn3wxSynL+zR6+OyP8yg4+ETXS0nRwWEjheJkIvsH/JzbuwiQ/EsZa+hhn
  38.109 +1JR6mwr3k6UgJ0IjdXV6J0ji4Inc+aP/aVTJJCbFrboAxVfZya5FuxwwJIMc1lEg
  38.110 +LXb2EyCDnmEinmf1JlUYRqbH6c+yc+Ek5FIHleA+/szCLjAajJZFJuiivJPuN4cq
  38.111 +9doZUEZCyPXACRcN1Pp4Ta8HoVnQVlggTeX7Q3sunwpSFclgqG0SK5JA3XpUfMQY
  38.112 +EoEP8lEJJspMEuibewVWVaoTIE8oAeM+d1C0JSP/Zb5ErtEEAOiAGZeTvt/znivI
  38.113 +FjsLaeKSGrbXVp/e4xiWLr1K/iVetxw/CmDKZxlCfsgrsOCWqNbSX+2NNmOhrNaJ
  38.114 +aYz57Z44NgxqxniEsYdT+4E4Haegoa3JC/jJD9hH+4yTf3FBlNd8WZqJWJMUezPD
  38.115 +MzMLSUf/wNye1QZTCRZBVlS85ZgDBAD0Ao/cvgOV0d5yoxE+cIuwpq+IE2r3mzx9
  38.116 +3z2FkVCrsaaR6frdn/OtXdZ/k34aII/dbQ/xSC7cpmtubvZaMWR06UZwKDOLvQ0H
  38.117 +QmdNSEvuGmWGIH3eo2OzY4+7GEm7lBBkft6SmUpJCKX2ssk3sYCyrxmPvxyB3hK8
  38.118 +BKFNUiOaJwQAsOe2O/CzioIpLikkXyd/w66Dkwc0fDuJQlei5vv08MEzr1JV/qcJ
  38.119 +tRHwzdkILZAMl1Rld19vuOQrMkUN2bN+wzY8odTDNfznL2sKIMJstymBNVOxCcAZ
  38.120 +E4kwimoWBDqeqmRiD4w8Ertgcl51XpPXQrHcz82fOiIvYAePXPRiVFg0j4kBPAQY
  38.121 +AQgAJhYhBEQtvu2faUNx9r+0F0BCeJwpy2+1BQJaXSY9AhsMBQkB4TOAAAoJEEBC
  38.122 +eJwpy2+15TkH/jVIGni6Y5fBr7oqMlMDBfnAfSeXNIZhBGutPcvYStzRhUFsB/go
  38.123 +RIlXaLsNcdg+AU9UlkMpvi9vggqIAYNQf98RnKOTLzl6o1yb0tmxbzOT0C9qsN/5
  38.124 +KpNC0eiQdAr7f7N7Zf6sGD2Bk3h+fsARZVG2pKCZLTaPkoh+bd7dPVLfr8vmLHfn
  38.125 +u+4fc/Il1FrKxD0nVSks5KzpR+ttfrwoJrZOwpADtMM7Xmfj5jT2XHRcZRo/n8x+
  38.126 +eGnVQicYlNzjh1RTu7wlaqdf+G1t38COsTCz2SGqyVYmTMlozr1B0vv2IirAmkn3
  38.127 +NYueChgKzi/AevtBfqzsoRhU9Xem9mS1mM2VA5gEWl0m0gEIAMpw7llUVEl0+18Q
  38.128 +JnfbzuxvVoyVM2JvvUjQ8f5GgmHqScKYZi8Of1PHN+jlf3F4lOcKomYPBHqipcOt
  38.129 +YNkj7h52Clu3vrBk1g8Ku1kD8TQL+k6RM1hc96+34rmt+HkAvYgEnXRpST0wkF2I
  38.130 +Prs1yL65Ep4xICMG55EZfbdgrn9WyN2iSAaxdUeG5jFzLMm11VTrnz+RQ2k4IwsE
  38.131 +MxUXKrxQ7yAVqBaDxDF7iyAQQy3DUXD0jVaz+wCriGNjQV8mFYa2DUgyr9vUM/Fc
  38.132 +wjIGqYqJxWJsXVL8A00tMV5ESs3o7WEhvbDu/KLfFOCsuDmAa7k7IdmmVy54511a
  38.133 +GbceNj0AEQEAAQAH/R95MUVIHBaTjmU4MJLf5KrToIQYyjVao/YHLihXM/wfHbqY
  38.134 +UQKt4VPYHDQkQg0VLylAeQEfApZCZT0n3m/D60hnF7MsvQPVmYYbKAdt2nk6B39h
  38.135 +ibcKNSPnleNCTegaGl1kQkqP9+gAfeFcxkv6z6v/QArCHnnzn9rqOKZi7J41S6Yj
  38.136 +AssyRLiMn7i7mH5jx84ZgHwZJ8yUS/uWFhGbUrRuF2X3WblmnQlOv4Il23WrN/HS
  38.137 +TQlyDhTW0V6JnkkzU+W5jjIoO01cVdgCZdReLEyBJeh61mBVgyeD+D5FW8tYh3l2
  38.138 ++wFHNJ4ZLxk+NkSVjx+4B24xaTCKbEtsTfOslaEEAMtTtQAzIpU6GF2YMD0dvqu5
  38.139 +W2FfESWkjRs4IwXqFC3KlY2DlhZZ0un++8kvkpCIIC66v0Cnk+fN5Yh7gSijPElb
  38.140 +LsSR0zJeQcy5CIScs7NF6ASYIsZmSMeSCYnEDmgqNofY/lnOfm8DEwy7vCBqycdC
  38.141 +r/e/aH2ItLo4zcXyBDKpBAD+4nn1PCCaYpJ7GPbtT3KlzeGh6QB1QrfuRkCir5y+
  38.142 +/ew6ly2X/93w4yJY0YcUUgD2akYcoEYmxgJevocMLQ+76aoCSzqLcfkifn9b/Zfj
  38.143 +e4tOVFTS+Cj1GoLcIgwGcz9aZsknbU0N1IO3e1zLS0NZu+KYn1VbkiDRHP7dAQL3
  38.144 +dQP+KNH95i+pQ07zn2GFZZa5vMCKfds3DggmKshwSzSNU8rxhGi/MnhmXASGVhp3
  38.145 +3ny9ZbL/qzQOPIkCn4VgpYiEZOTQZ7CirusKftXYkbWhtWcVMIJXivS12Ps2eJcK
  38.146 +KUVWDffEuV9a9A+eHcB4c/AHvqyhV60gtAICLBqHRDDK/zgur7QxcEVwIFRlc3Qg
  38.147 +UmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgA
  38.148 +PhYhBMFOlnkDKecxT/WC1fAxdmAvZZ9dBQJaXSbUAhsDBQkB4TOABQsJCAcCBhUI
  38.149 +CQoLAgQWAgMBAh4BAheAAAoJEPAxdmAvZZ9d6F0IAIpVRoHbfaZ2goawft6Mg6dP
  38.150 +rwznM90bDI9gq0UC5Dt+nShUhgTJ4wSz/iG1XHD565ML9HHkMsQrZazstNM4lJqq
  38.151 +AwdIOMAQVd3/sCFX/8bEPO8UFQDPB0XcdNemNqfbC1n7kQWAFz9GV3Dc3LJt0cDT
  38.152 +094G1Ta1gyuVbuJ1ZfI3McQZvohebobIWkx0krdvHw2AfLBzItuvpzBOSR/ZHGe0
  38.153 +xK7FcmFxfPQHNfNSyOSBsfC+MILvwkJYTuSRCY+Lk86e9pp1K2q8xGGVu/tdVRSF
  38.154 +Giw2fuhEpL2b/daxaZ89qR9y+r3H2ycwJBTbpXIrvsbLJB0nBWEXUFiHJbunbEud
  38.155 +A5gEWl0m0wEIAKyzpLNBSEf6YWKIgKbF8FIbk5UI5e+wF5slB9hznmTqMWsmVDYa
  38.156 +FOZBWq4IkKnOP1wB4DiaLnjmwSE49Fw4tyR5B16frhRX7cYJ8o9yFI+6WA66YQlf
  38.157 +Quhf3Okfov0JA683OkU690MaDmYbmU5+V0LD2tHcXPo8iTp6opUA2m8XnZhwUZxx
  38.158 +2s3X0Gru9nKcvrr8Os7cNtM+THyUuUK4yNGzKM5GojuoGhikM6ULPw4cfVuHRMMn
  38.159 +AMZMx5sooJZ5yBx5r/FBV+os1TKldLpNXVr3bIMVpU8jU3ca4t2qOyUGBY8WsKZk
  38.160 +o0n7MGoea3bzY3l72BDHrqHAduBiO/tOPbkAEQEAAQAH+wfIcsg3TXQc9w2TPEUH
  38.161 +z5xLrNt/Eqm6JF40DYX2M/G1UjPTfuEPTNjRoi4MqcRVTKqvVPUIEccWEycVo4GS
  38.162 +dsJ4h9n+VUCKc+dEZH+NcxrFGZnUUXI0LlY9l72T1OsVYGqhkQk0rpcCEhsM7FxK
  38.163 +ulECdZaWmUQXvVF63F/dsXpnIY7WCnG1l/kF6pnJB2H8e11bYWJ8RZOrvO1ACUS9
  38.164 +Pgll2ykTPqeMw2674IeXH+r+MXqYVzzkEchOtLj6E0P+FoeiVsJGoAah8DYH/nkY
  38.165 +TjAwBW7GbjR9gbGzquFkb82BqwqAPRefav7e3eDFl0U+UKnoI21Ru87SIAgwLGvX
  38.166 +OfcEAMSRPjGc3H3Ug0F+WYbwn4Osegx5liEQxc26w/mDaBSPgIHktnQ4jZDzhkZp
  38.167 +YvdoclSGULUxtbxO1DH03RGLirKAZhPKxmIF5XO8Lkd+RHjqr1HXsYNii7k+dR5M
  38.168 +GkMTBB+K7/O0UKueOgvDMPjwTdlULOCdiM+scDThbIXcklCLBADg6yW0ttCiZFeq
  38.169 +/W5fg7wE8OMbqnapdkEkvoZg8T17NoyS+46OaiBNHxv/OKdTYbNObPTfz5AnGAp1
  38.170 +hR2OQbnzF9GzliFPfkNoOedsPahPT82TeKdaJBchosCAIc73Vqhxo08fE2eDf7wN
  38.171 +EF9hYNke0hKRN/HY+Qvh7kzP57mPSwQAjlaWGKYkoX9P+JpcTVrw4RhK6t4dHWCV
  38.172 +ZpkMXYVVhPu8ZUhes5fhVmB69eaTPe1UxaLpO5VWxaCLcW4iA7zHg8C5JIqnISNk
  38.173 +K3JN0L1O9xX80IyYhADVRDs/wWOWJPiU1Z3FYhnJKnKNengJWZ3d9gr4DPDg35l4
  38.174 +R6shypIaDBU71IkBPAQYAQgAJhYhBMFOlnkDKecxT/WC1fAxdmAvZZ9dBQJaXSbT
  38.175 +AhsMBQkB4TOAAAoJEPAxdmAvZZ9de4cH/28GI9U6CzlXSs6e9zkZYtjqWwGZSN0w
  38.176 +Kp/pK0W0dtx2x1suxXo/CIS0O0nPq4ylIt5PxC5rAMTeiGXjf3+3ujONem1GEsBw
  38.177 +S7A7PThFQz7tKMlf5TfLp5LnmXVehuowspGnFkESYlVSDKWxIeGB70mJ13CUslsG
  38.178 +YwBI1dXzArLfFW5hC8oMt1vPAO39TsOJQm5Gig2xKNOQrczv0TCdM/Ql+nuTgyku
  38.179 +mOWnEwhJ2G8Q6B7afHYUcylVxGDrZ8GP+owHvs+Ys88r6Aj0VGOHlMtNjlrlTOJ5
  38.180 +prBUoObzPVkJ3uFUdKvsKDBA8fHpuN9mAT3Vmf8FDZvFV177zuTdY2WVA5gEWl0m
  38.181 +8QEIAM9eLiG5hC0uyMRgcdf8OsP4bktXV8hAN99SQ1m4B66470TDuLnSl+zVNrLH
  38.182 ++9IfsvUm68J/KWj65e4jn5wRIitInB4SCv0w/2BjB/xONQmhDxxCyhiUxM59VRSs
  38.183 +zcXO/5Qj3XKLhuWQq8V4KYGpWsA4uMM2HvoQ0hv8s/sqk6JvsiXGo30Qoyg2Y2JR
  38.184 +cy+X9nHN5tazbd29+G0GI8IFUvtA7BsBe1iKOGe14BuPdlV2ZRT3T5WPO6oXDOvM
  38.185 +OQPfhUzN8P1xhLDH3ovmKq0SVigDU9oZRZcqqdaIq8o+3vSfZVHOK7wr6sdeTUed
  38.186 +rvWysy8MsC4GqwgzS3WIM+KM8HcAEQEAAQAH/i6hPfxlbByA5bKLAW6REGHa7mpQ
  38.187 +tLOaBTZZmD2HjWqzuVIcNODMQ0+FTmx7XdwNNr+7xc4RrC0oJiYbqpt8mtNi24BD
  38.188 +jGcM6pAxFK2epHyK1AwF1M4cPfk047nndcoiVwRn4DcOuwHKO2YHNEYs3/RTjPCQ
  38.189 +rfyLZcPXWl2DYHlo/oqXOPUOpaXUV3euL6KeSyhbvD0ZkNe0Aaqbc6PnfHHH0hwc
  38.190 +1ChJpxbWewuFSREb+5LCwWixE7JbPQF4AKi8UIWQgzYhkaTHyjiP872yMci8dH35
  38.191 +Vw3dWnQTUFrJcKc2nD7H8bBj7tas0r3vqb1kcJTKVVCtELY1wWkr6pJ+8SkEANQI
  38.192 +oKitXAVDVKoKYmdowapDEuOTKtA736nPc2kmVLZZrnJH1fF2DoTaAa3BZtz2Jz9M
  38.193 +gioSR8TdSVX1UpYLiSWnOO3keeTsaguKOwu98eYAMr+LxfyFpYWVqRge9mDenlyl
  38.194 +DR24gzFCQam3RBtsbwct2dH5dlfvDF+RLFS29kKLBAD6XeCxljI7vP9fHet6uvBk
  38.195 +oULPjW8vbKmzVzezBzLEvJjjRPzOJtMxm62HNe8OK3ASVOpvKLtXQ4CdZbzg4r7S
  38.196 +itRryGc8/PRYldMjj5p2dmXqeixbIYd/otV1lJCuBOxscszkzcwkAzK+ye203uJS
  38.197 +68OadRLupydhM4gEO7wjRQQAg468d4IhDI0BgAtXjXZttVTSEfT40oLxnUDHJnpQ
  38.198 +vfVz8UdfHOrkud74USNO9q3jhgW/UdOkqvJEqxv11+8+8JixzQlhMF0AVRWrSmjZ
  38.199 +CrbgJXQLSK1LMPEV2oDBKsf69EgSXh2smSUaw+kga+exBkaJzSREVmRoHHVyPQfF
  38.200 +y6VCILQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhv
  38.201 +ZmYub3JnPokBVAQTAQgAPhYhBGxW20NhmLO3qpPVNiGpbY7FarzyBQJaXSb0AhsD
  38.202 +BQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJECGpbY7Farzy7usIAL1m
  38.203 +6lm5FnX5Ja7yDED7EeR0IMTw3GZnRjSLHkDR+SQSOYdXvcHPpk7W57PP+Rvh9tbe
  38.204 +/4C8eaNuBchBdtyLm2CBXIB+91FlHkUDzap54Yr+nSUCQdI6vcJvqx1ryE3Lye4x
  38.205 +Hs+mX+AQc2T5FI2jIUoI38fEhPjZVy/Z0w0EzoBweI6g4Wj+58Wy+lsYtuDFMCvF
  38.206 +Kb7jdG4hGSr1I7e5hZo6o2Kev/wxiOwIG8c/OX9z1Tby+0GoG5wpCWp9MhG8Nklg
  38.207 +MiDtKsfLfwAn5XdPmJaEYp47KyARGI2iiA8VS28tkRGMMVvzFJ7PlTzVU9b0jpl2
  38.208 +WKY9oDellg4ZgG6p4i6dA5gEWl0m8wEIAPirNF+Arvjpu27XnwMwxi20MwwxPoLW
  38.209 +gxBFXph/HfsZL/z+GpNZBRkTNoWuFOIOxZc8OgzbHgbZAsuSM7eiH+mtgYm2DpHZ
  38.210 +cRyltWOSu9o1tPQGMqp/0Pu+F2Lwceuq186s7DLBs5V5a23Azjk0wpNWYjXyi2rn
  38.211 +vT8bcp5/Yfn37+LdDmIrRE5+l/9+3FvLB2tv1ZQCEaz38GkI+rAB3RJdRtrj9Qn0
  38.212 +nYi77r0qmQIruZbCq2cXXRntftaU30OcrTvdY5REdw93wPeOuE75h/pQScnr3s9y
  38.213 +nVQXmzSszAP6TY/T6o+pvuoiZhVzZpU/1SKhFKdjT1UJvzGP4buhtWEAEQEAAQAH
  38.214 +/ithaqSShXPFCr6+fO4Ijzof6pvg51/Z3klzYJpH6soITdfb2HUGHZ6PPH67rMb2
  38.215 +/r9wcUwW2bkmGJe87KrHbLvOWf/VM9t7zIDL48X4Li9WGThM8H/QBnw0YE4RVj5f
  38.216 +soBKqHX+Vr7nzLb74L4YFy2u7zksE+hVfy1IM4m0/TmnEDhpcBtyg6CMPv658Ae5
  38.217 +TDFIAT3isWoPPBvgKEmjw4ku4a2KZgfdWmqurNf01/N6SPYp2XeAnZNYhLYt/CL5
  38.218 +9QFjxuPfwT24LWieBTi8R65txbJradyFvMoQWQHtXChrO7OzHRdRf1D3kV2NaJTF
  38.219 +yqbhrI44x873RgHD8CpZ62UEAPpeEvD8+Uf/rWV32GxTr0kH+G3JsE6Iac673eiu
  38.220 +R2D7IFR+/mKSyZJ+HYNf1b6BglPd/3Lx3txBHfNCJN572b2pPOPCVq6YY3ErOMng
  38.221 +NvM9md+87HMqTux5QwpKkU860klmltfH8RnmpD3beQ4vggNjWn/xpIUmmZM7QiRB
  38.222 ++yCfBAD+Q1jqQY6G+dhOQD7n1TSfUZ26SEtfwNUEygZSkMNZBvNCjiQkoVKI/eu/
  38.223 +S6Y5xT21J/ZNrU8jofjmlb41d8zJ1erxtcp4KMR72LVd5vIKkRtDECzBskUMA6tG
  38.224 +XhvMjHHWdj8X4C6LB4DhpXYZYlofp2Y1xed/G+V1RTv8QQVp/wQAhjhzeHi6+iDk
  38.225 +ZhmpTrG/3ZfAn5OySgtJvqYXABBbT4/P4O/kDx2rJ4cW/zN71+ANl2OGxDpVKlGb
  38.226 +YGM9rbY3SPiHduOPwRbvZLaW/tcrhr6YHtFckNkL6DBBSifiJaq5yfFHxlZk+8Vj
  38.227 +YO/9L8JGNB+SUpiJi6Ikv0VHAy1fhgxLcokBPAQYAQgAJhYhBGxW20NhmLO3qpPV
  38.228 +NiGpbY7FarzyBQJaXSbzAhsMBQkB4TOAAAoJECGpbY7FarzyIJsH/Aja9gn/4WQT
  38.229 +hqFblBcU7KsnYk+5oSUWjhJFTb8ChoiiPrYgunFhpAQUwZ3URHhCXlqg4EIOhGSx
  38.230 +LNrSxx0mOMmAxZumir8gCTZY5ktcTJmnrah6ZNOQkInJ7S/DGDKkH9wir/bpaS4b
  38.231 +zKsixN8yneQp+9T6+oEtPqTiTm25S3LB6JcPaLoeU95H/fqeAXfk1AsHT8ymlcou
  38.232 +e8Auq97tFdQKu2SWbHcIHevPjwY3EI7+SR0rL5bZQR7aonuACueAob3mVXGtJ77x
  38.233 +pdNw7zVwwXnBN/af941DLi8c3Tr23cutyyCOVMLgjUhcAV+LKzJIfVd8Hw+8IPYN
  38.234 +OSmIbmGb1q2VA5gEWl0xtQEIAK9/miPAeUsAhHqOJHd5oXMMKNy4cvkoIOnCFdYe
  38.235 +N4wFe6rW+A0eOhH4DaXfEjAcVVwmTXAp69s9vug6C55vloDo9FCIIA1dWZ8qaAky
  38.236 +Z3Rvby6yrUA6jXiTXbqzNH0XkLHyXnHUqy2xOpimNMhnqtEhxuENcpBTsjlT+CJD
  38.237 +JVtyKZ+fJ9Ug/52GUvK/+a1xcH3O6kNGFZg9VvUKmHMoFKdivmFkPhmiFzg0rOT4
  38.238 +FmIiQfNBBaHavjp9eHUz+R9S2MUU1iAMFcBNQttxrsm8bgtwgL6T5Rgu7Q+SnOtc
  38.239 +3CzUUBbmSsmVQnSqQrNvCeOTXIt00tBSZx+1XvbUyBzP3JkAEQEAAQAH/RQwNpgU
  38.240 +RR+2oIbEoTdJO6RTasPxR/CXiCm71O07rqIh41cEwaYoqv90LIW/QoVcTQl7sn7L
  38.241 +o8ElujdWrg18wrBzm99DuYQwD+Y6Z5tfO/1t8DlL/pgb5DhRo3+dq9UUB+YgfnLT
  38.242 +xxlLgPUccYf4PPMv0oQDGwG1TxQ/L5Upaju5lnIduCDqxZ7dsRaHLJYUC/iqtbDS
  38.243 +JmpJfirGAub4G3hjIZSZKuwEQG9wt94djbNGbHmKQoINPpcEgK9P3duiL99q9gXI
  38.244 +PjVfL+9Rw+PWe7302zvU7JCIDmZ5+kyfI/klhRivcY7hljAPoG3HG45znds8mnUI
  38.245 +V6iQcQkCUofoC10EAMmI5KzYA2pLVlL2BxCFH94XNlxhUu2yEHWQERo3OzAN9HEu
  38.246 +caNxLPN1t7cRCa5O43yQvf9+3aww1nVfSgEv4DT+s0u9JBonGI36QFKG7JMH9TE+
  38.247 +a99Mx2aTMppcEueO6HOAbZchWL8gTihT1/Y2W+xDHFmfwRRSUegO72Fr6XAfBADe
  38.248 +7WXAAE+VVVW6O4iNboUMc3nyccvKvasDroTUJTU9adZHO1fyiCinWkUF5SIPn6b1
  38.249 +eAP0xjFxpqpQ4wcqYMs/6+isa3RK3dpfBQ+zv0Ay4PYXe4hpk/dEQIfH7hTLApYc
  38.250 +07YNql7oqyAnF+xUuAJJK11oU1igS3dx1Lt66+W8RwP8DIM0cqYtrOn5Bq0LSlDe
  38.251 +Ml7stkiuCywU/Gw7T3apmqtHZb00aj4piRHjWQQPzFlCDTmgRQX0jkoUlGXK+t18
  38.252 +a8JBJbh8zmFHGTUTkzsrfHSFS2IPKzfBlick1Eh9vVdMGjd/3YsFFcIVGJntZ2LO
  38.253 +ZY6kfCFYr8hL5iEzba0Q68otcrQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVz
  38.254 +dC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBCobrRZlujMFWKzJpPfP
  38.255 +sNj+NmecBQJaXTG3AhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ
  38.256 +EPfPsNj+NmecinEH/0+wUlJx7pc0oTXkLmioD4lLlE82TkwSVvHT6MxGMtYxjKY/
  38.257 +s0MiCX79pNyXrCCbA24mA67t1XPQpoEPRVknEEAlfCSS55Qa9k//KuMugFC3HvaR
  38.258 +xy7b8I6MUzLeTJXiF7jGdkhcoinrEt77tTncJIK7WBHNRgP7QUcA5I52vU1LbmzF
  38.259 +D5PuUoaQU/BWDfxf5sLTdpIIyDXm+n8sGnyvIgadbbFTmOLwU9EmuMrg9F38grAj
  38.260 +RczL5QUsoMATeEAfpsQFQZglUqe41uyyLy9uugj62w5QjYgaJdURLXH1FYyhM/zf
  38.261 +JUyEYxuMxLTlG+gShARRGD5eMnuuAstdlEqp1ludA5gEWl0xtwEIANQPXF56qCUb
  38.262 +8dqxvDXf2p/kcWQLJCkRP/6xyNIRty8Db2FEZ3ADG+QpZU5yC3yJ3ixoJkoFa3mo
  38.263 ++UK2dLq6nx1FC816JnSnsKlu7psomaaqNpnEUZiX+46oSh3B+hOAS0m2W6FURb4b
  38.264 +hE6TD4XTWnABa24z2WGiugRpx0GZjUDd0CEbShC/fX3d1+Bj/OPfXR7Z/YD+rglr
  38.265 +nfaauUMB+u1yinMOxnwob4Q+5gxUGS7+hZ4+is5SYGPCsN3KKxUdlNip9F2lyErt
  38.266 +ZeBmhNKACZ83RQvJ53ayY9Fs70Q7srY/R/MVoi3B+aTG1RD9AKBaldFwj8dhcxES
  38.267 +gNYZaFZmKBUAEQEAAQAH/jkOpwJOy2Ysti7rKqJuSFNEMpRCASlBmG/towSOurSe
  38.268 +Hn5T2ucDFyKVVso8GkYYjFxza3X4LlpOMj8We6LwaraD6PCRAL7bjceQ7wd1bZ4v
  38.269 +50AJWBEQN6HDOyn1ktVjbB55v/7Q/3Du03MW05Lk8sz3PNIqhj9ketuMII5Qg/aj
  38.270 +GlCKligClvcEK3rqEm4riTafXoc3KGZZbmuGewTzXRe9/VM4FGohaaML/AJ77Oh3
  38.271 +MCE5Dp5EzdPBjqF/JBddj2ClmD30wIQw+miOE/I73qjIsHaK6FuSv5AADcJiKg1g
  38.272 +7Zj7ihxr1LrK1m7QczX7pKjqYGBmoftJWSpHqkv7KQMEANiN/n+gvpCyiD58Lof0
  38.273 +GBvLspPsc2zPZOCridmUpdDk6yVgSA+4iXM79a4pPqKL2JzCypGB6jdCHweD5ACl
  38.274 +ktngJZE+nzzAX4SrGooitg3WbYPw1xSEaw2yUUe4UIXIzMulLzqaYhsXACHQ17pl
  38.275 +sgIGGVZ0Vkn1Z9P5+swLz1ffBAD6r8eCnc+fcRjOTOguQMun4Fw/csP7Q+LprMH9
  38.276 +kwR0QusaLEGiZlxukTbq80eHmlsskdSXnE6MwlMAjTrrZjRrGvB1n5hxPFqjOyth
  38.277 +JESlamNe/Y8f02esQmgLIekfRdxsJbK7+50Ab8YsngqTYLgWaQhjTk+G1heu2M/d
  38.278 +X2TOiwQAyqdz1j4KUTS8b/yo96g7ozzrtZCYX4QmIbcw+S1GaH9kfalIqDiApsWO
  38.279 +XpyrBJdoanbsV52+2P8kRr/XOQA3AwsmPmE1Q8Cin9CzA1eMYXzE5smo1Z6nyUdu
  38.280 +pQEiKZ3tjALyy4QqicLsYtjEOLtQAcnXT1H0uIPF2f5dRUTNzr0/FokBPAQYAQgA
  38.281 +JhYhBCobrRZlujMFWKzJpPfPsNj+NmecBQJaXTG3AhsMBQkB4TOAAAoJEPfPsNj+
  38.282 +Nmec5l0H/j4EZBHzz/cI6fPzZqYegoPZ6rdHOu0XGXo0HfuNX4p3qv8QCQi6GVQQ
  38.283 +pi09W9sAiF2M2Ual9qC3kuo8nq7Kbuse6NBIxDeW2F5jamyk+Ffs+GI3qrwMzD1a
  38.284 +ZI4S9wiPv3Wq7d0zr/4Fe4AFSA8kQY57y5BTN6QLXPN1srIxfX/2rAleIOp1Op3r
  38.285 +H+0bmt/6xhGsGVGcCGpuQQaW5w8FEUQ8TKi8iGHTE/l4oT8taZVHvJPmUSwZGL+S
  38.286 +yf1z1D2e3kK8eKjlji/xmCQ8Q3OG/9/yRFThKzf8S1vGRit4eVXEK/xXXJIgvVyp
  38.287 +MKStK1jEEkjA9HNdFj3/yovCtNrg+ACVA5gEWl0xyQEIAMOBGlyKbQxEoIGta+Ja
  38.288 +TdMYXXrt+HVJo2qatQCJbXqIJQauUZdP1BuUflMbkkAdRPC4XS9JMzGSc/nznYL0
  38.289 +I1rjI4xwRWSJyatD196RF1E9NUw5i6ptX5JRwJp9PFZaVIxQghAMT86cJjbkYYG9
  38.290 +/5sg7I4xBrxJfyewbFum0u1BAVgSa1I1faFcE/Z2gMESaHP03h/SHhqGigambJkC
  38.291 +0KY3q/wjCNF0QHCCb1e9CRzfiJLdqOprmVhS58M8JNjJ2EXvVusc9d0v/7oVVWDy
  38.292 +V6COK6sMSdhMGXz3uPTuA61tR0ufQaxYiGtpI4krugSbTKmnr/AZiVXADgZ70zHc
  38.293 +jtsAEQEAAQAH/RDPA8SbEV8YDP8fn7WGJnsuW0zBzJyagfzpyjZ+mk89PCAdhd3o
  38.294 +uu3+gvhQPlXAbnhbBLmXcia78B64WrCzBTfzBjZn3LKuw6XNUnAyfa4gmt/jC4AF
  38.295 +B7RQm3egEG6RztBPIUkriQNuTdbNJRj+v4At53vq+SitEcw7kRI1y8+I1aj93a+s
  38.296 +ZgfXoYhSBDzUR9o8gwjj/Da0Z+HYqEnxYhfwohCmjFvITb1JMCqqY5jc1GadYmrb
  38.297 +t8MQ0ab1RuJCUwzA6y5X6b6WP1emKEZZ5Sl5ufqcUJDO4aCfjCAtQYtSaGAoMFkS
  38.298 +YihdlN0eSWK8uBqOdgOvONRFu/GlXtP7oKEEAM9H/T8FMASIDQaHlgnOolEfInyi
  38.299 +ztz7sunfnF6/sLKIH7IoBymq8t7u62Q35LRt8IpkIoFxq9/fdsdLjjLH+666zdkV
  38.300 +UxrylYd+1Bl8YpCmIRs4t60rlJQNUCTQsmE9ZDYw67hsC9Rtl4QJeX6OEevzhvu8
  38.301 +3ZQYa7S+rjwuHtKrBADxdIDbLWxLJ5J3y5mXFau25daaWAK9pAJ+1paXmCpvLwHi
  38.302 +x+VOOHCS8o8wrWZfGCgQTKd/h3Hw+Xld96j0fqUod7tsZ2q/5abJDavcZUa7rPnX
  38.303 +nLBC/gggu4CnTL4KotBsxc5GCLN9nBy23YTP6V6oxlS6BvZLRwItRkDOWtW0kQQA
  38.304 +rDmzgZDPQp6VpYd/sRdSV1WosbkBt/6+gYPh6pDnBtBVDohndQtUUDdQ6IesKV3y
  38.305 +hgNSmpVX61Kp0X969dK67y8BX31DpFmwRTnaCJSMBLbusSUawl5sooOApePowPUx
  38.306 +Io7hk66V+2aFSoWMrqRNkteo1c2Sk/Und8GBD1exWnpKHLQxcEVwIFRlc3QgUmVj
  38.307 +aXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYh
  38.308 +BNR2FlbOV/s6/YTeywTsh7QHSqG5BQJaXTHLAhsDBQkB4TOABQsJCAcCBhUICQoL
  38.309 +AgQWAgMBAh4BAheAAAoJEATsh7QHSqG5UMQH/RgusteCnkvO6tv2ksz1Uc3Im5aR
  38.310 +poTdF/vx5R2MRvf6pbPx4HG7clWiJrAw53xC3Jw0+LeuqKs7/hPitwgTmGtdicVT
  38.311 +irw7GIXv51gnzPud+43ETT/e1ZR8xCc+ZlnlzfYrRCFkOkwdu4SxFAWww8QOE3fx
  38.312 +bkrL9OFErAB2Y2Tvcwzu2nFfQblWURaKC0IRrd4FgU4MCRzcCfHY0MHLNG98bpnT
  38.313 +yPkMpJ2s5dodpP8+l1rlNN4LsXEc77fd15tdRWIVTILbZy4DnsIKpb6yzrJxHnZK
  38.314 +LQZJvGSJdOR2dTQN8XdB1kfRSJ2S3MqE5taMISf8jziGgYS3R5OBBeKIzCOdA5gE
  38.315 +Wl0xywEIALUENfsslNFdAAK/1d+nnAM2nox9ZNczDyj3kjy3i1wHdsrKQxEh4zY+
  38.316 +DpuGwjil9Y52JdzQBZTA5Jp13BUEwCpTmBUBEbkR24MLCo4U7o2bzS/bPbmJuCDv
  38.317 +B8rU+mLPGzaqafaW/Wgvv3qNV22j5WzRAGTJ4tmYWKXC4kIK9ovF489D0965Eg3e
  38.318 +5BWr9t+t7v3XYaULYlbadj0ZxxHOgyqYheHPCGxrN6r5y7sbAwz2aeEV2GcngBRT
  38.319 +NYiSKMoLYc+Pt86OmRtDJhp+hXxJLdslEMW92QJPVgLBLszBHIHjO879UkKfvcc9
  38.320 +hlai5niLqIImxDIg1fBoNmJznsWzvbMAEQEAAQAH/iwpOVQsRagoJKsHCxHzzZt5
  38.321 +FUgYBWR85+tqLqqSarTKe2Aw5RjGaCyhCiZGQ5bXYiddypHqzBnEz2ChdU5JaOpK
  38.322 +l5U0PBMm+KMpK+uKzsIMawwMVCwyHZInToLc37MAbNayz4QhxPPIhlHLLrOoYv3f
  38.323 +pVVxbV8BjErwVwueqhRiCzR9BZehktTewhDQRv3HXhGIBrFUObtSFC/+JZs3jfJ+
  38.324 +rxDWa49AHK/Be3KrGwOzteraqRWSSic31RmFKOG6SZAKlcrt0XlE71jjiK+ssqRD
  38.325 +8AmYUtXtqYm/WyEPJwdDywpf0N7nBalSay190vylbVdIIDjZTDU+OJZXMFfXb2UE
  38.326 +AM3ijs87P9QWgd0L7YPaeaHBGvzmEbnoQt6Xd9UfmzFVUsx8RKhGnF0fSIap58ag
  38.327 +TiZMYEbv6+lV2MEGUTSEIJ2lRWCyHyO+EYwqnqpPBu+ImjS2mrlglBbemybjUxrB
  38.328 +nXF3nhhQlqlgnrFPCTFSs34bodqFgCRsEiDLnFuULaEPBADhFADzj1IJ2YZGL7GY
  38.329 +XcQmy5TA4vRTO+knpTYAfqadq7p4nR3gD5bcyhYrymV6KvuDj9UesQlNFT6z/SFA
  38.330 +wwtWR+ziPit7r+suS2HSA86MF0ZJFLo5q6J0D4kScuJOFlZbf7s1Yv2IzIxlGDyB
  38.331 +RWFkeIpppY7tgN70E355yMGRHQQAyS1O0yke2WOgGPv4fcJpzOGeMsujJGoWn4C6
  38.332 +LZMeptC/Q1idCCgMGr4gxfwFMjo9eVUnfsXAnFU+kTktEM4puxlWjbMMKR307YJY
  38.333 +pNsN1PL9G3eaMGrhb4TIbG6MiK529GvihogSQR7VUk2yPRzYy5e0obYqa9Yt3uyJ
  38.334 +OcHy/ocyvYkBPAQYAQgAJhYhBNR2FlbOV/s6/YTeywTsh7QHSqG5BQJaXTHLAhsM
  38.335 +BQkB4TOAAAoJEATsh7QHSqG51zAH/0I5IqtOPdSm7TTK2pcBkVPJXuaNR+HXMsH3
  38.336 +qWZzG+M5obqSeHwiH7+k1ygrxDpIwjnWkcLYE8E2vK1iP7xtj/d5+VdcQ17bIFIp
  38.337 +QLtmW249tUoiAVe049MNnRSts4ysTNIZqjaHreiTRUk/1G8amBbxnS743sD9bXzn
  38.338 +nWs0znK6DbZ2yon2k5igDIGdsC6TYSn6vx3v3H9aGKMX/O458s1St3NDyVNfKY1M
  38.339 +GEMHw21PLPUNQgs1GmCIMKwG+LoolpBKKDglhffZAOFl7UPN3PBjYGwgqBXHqW6O
  38.340 +g6Rro1Rr9QdERbki3TzE0UBXCISaRRR4msyesxFqsukQSVAe4H+VA5gEWl0zNQEI
  38.341 +ANBWOIhVaTRhZ199H1O4uJTDCMGJzLywJTh0IhnS5HguQe/bo75eCZO6z7mTQTrG
  38.342 +9NN7A+fETcK8F5eRgY7fJ0Oze8cKIMLfNorzWKKRhkOpIMmbIYx7I+gobgcmvxy2
  38.343 +OdMFcHfDb74x2nxW6XJNhl3ZfjPk8Hd2qPHV3VJwwuFAmXo+zjbvAbVXbLE7UxCn
  38.344 +z1Qv5XBYReOKkpQq6Q8vFnQ4lln6fAvotijvCVHirMJO2VkPMdU+1dy57+aG/M71
  38.345 +GPjn3SOHSviq5PHxF3p+N3uLe4H0Eho9RnAnfv1OrXTw8oTRgWxUXl+n5/ofUxPF
  38.346 +4xTV3rLGFhCW/d0w0nD5WwsAEQEAAQAH/RNqtcIfE7sKCPRhWPYYlTtoIfzHtwku
  38.347 +8YkdacA2Y4y/4u1T7yLi6MmX85w8GSw9NrwvDuIe7ZBkr1409Xo3WhV5OOQIEZ2X
  38.348 +6CFzJKOiJH1R2fhwOOQ65dHRUs/f0JgAc8szCpRe5p83TkGgaAl7KDa++oAjqjW4
  38.349 +HW7Mm9//Gmqby6LF3eEj2PiMX91ekBV2z8pjyZLkBoNjaGMhzqHh9SDfWM8GvaWp
  38.350 +r+ZWk71a5Ml7tIBYVSkYXk2JdbpttAoUTw0wWe7nukDhibWlGnhivT7DzAAMIz52
  38.351 +MOuYLS0HTFpqk2lrNOS7WS1RF5XtevHPFpFNU0ykIn7t7BRjmEw5twEEAOGTuOs6
  38.352 +UWLaXfWhCmZTdrMV+7mBbULvnsYkiSiKr38A4/G+8e5cM/77LK+zQwXJqvL0CQXb
  38.353 +QzaOKE5R4Ijx/ef9v9yGYrWToj16XLDIIdtUd74szF+pKYgwVrqkc49M/T/m7eNF
  38.354 +ZLYYYErVLcnZNmhStgvZ2pMQotA9x7hX9T+hBADsb0L3pjQ/nTknhkgqxJ1b5jSt
  38.355 +FBGt+rbUtkmpkAqdMxnlN/jEJ8U/TwR7/ZH7nkG9/TblAEobdHetJzMBtAtt8Uo9
  38.356 +VXy356QftKdXNeofZpKIsoefOITuoAAC/0++W0wjx7EO+4FDqUJg/9kwvWi8oMRD
  38.357 +FvlLjBdCJYsbHHPLKwP9EJvKiTYAF3kF3gyqBCCviMblkbTf8whAMlZBeZmwM6Jq
  38.358 +ZIIkcIhtaABPRUDW5QyEo8QmOXrbiqs2Oq8Z8R2aM84ft6KMdCxMpMPAOrDT4XZe
  38.359 +qq+oGp6p4/cbVmIvwYFJopb8wNaWQk2ycI8eyeogn3HRG1pyHvupXZg/hRRnxfZA
  38.360 +fLQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYu
  38.361 +b3JnPokBVAQTAQgAPhYhBM7YCWrhIhaAwoSH/fd6hr7BO/PYBQJaXTM3AhsDBQkB
  38.362 +4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPd6hr7BO/PYXn4IAIIMMeSe
  38.363 +jxp0LSfLcUSbCDLqWf4kv2650pikN2YSWe8ZoCrR5tlO0cWapalJWpTA9gnEpxcg
  38.364 +tHGUNO4tFYoeaChVPs8sFxlO4lbDNfE0elUnDpo9Ct9aKQRhO1f713igWRN1KKrV
  38.365 +Nh5AZXpOVpYMo5jCQMX26S09JzKWs6kf6M4oszfyqTQ3wraqnq2E7NTm5mDTpYw2
  38.366 +aM+XwNPrIrqyLCHt1kqpBXHfF7wnSu8/QhOfnKCRpspwRrkqimXuGb2fbaYR/ySS
  38.367 +7PaaG9wjQrLmZB0ZAq+IxUXMkIzkOpOxzm2HUmqps2pl6PqaFK7annR+oocDsl07
  38.368 +tSJnB6rLAHHOCnadA5gEWl0zNwEIAN/DrhSP5Gq4L+EjvWXdq08CevJbb4k6vDqk
  38.369 +Ig4PiIP0Tj5o2y+sP0NJsO2CPhus1El0KdD98J06c1K6leJKMFSQVWXLbm055QXB
  38.370 +Zi4HEaCd8Y26Otv63t9UCXaiEpUqAFuPr4GOY7GruyAkDA+DgYW77E2pPkXJLxsJ
  38.371 +tFoEcQ2hRSqBZ8a/56f+ZrbIpdsvPG9CGVyXvrSLnYqWaixlKJZNx2lQRNo3pOgF
  38.372 +/GkVMSOIpyxf9ERuZnsjJ9eIslj+oxcrNEfAWtqYNGO4NZlPf+hxl/tjp80bY8OX
  38.373 +R9Xhiy7F59H/TY7hWRfsZFivOr2Fv1OWhwAWpVxFHSe0hkqDesMAEQEAAQAH/27T
  38.374 +UQXYGq6MmRIuDGFGf9E7Dj+4764NDCsTHdbO9LM+Lf6VGnIrIo4mEl4gErjMSbwz
  38.375 +r35WN3T3/SQtS4zvZ66KafFn50Jr2TWXiw8i6yUc9QVYBkzrnLUJv0IllYSRb+np
  38.376 +aWiGaHQX9S8/C0YnwN/GqovwVepkcVM35D5tUr0HhMPGUyQTZsT1raQP22lQT06/
  38.377 +hT39MRV1cZwEwqYBs/MmfHkrbNmT/hGV28P4HxpmEbf69wTjl4X8SqXPepaXWmlf
  38.378 +5MWCs7B27ix64RO/bEjj9hxJmKW8GZupFWugETMc/GmDy+f3TGhIbA1t2sxq9gEh
  38.379 +3BWjioQTTwdHzpkPi3EEAOqXMk+GFHGOtUXF6Obm0t1AkgthnpH67+sNHA4IkU3M
  38.380 +tSznZdsAr4hiHhMINukB0hdPufKGs+bXCA1sSTGswrWadSAK6x2WQjhQ/nTz0kK8
  38.381 +AHxJ15az+FlHj047MNJn8uVfynfLLFnIfsWxdtSsb4Xtd29bIHe8iKvasYgCDuXr
  38.382 +BAD0L4wVp5jZenjY75GZW0FSpExROksqgva6Gu+8KBVtK0OB1QlGT7vF8b5ibW7W
  38.383 +9XdnKEk7yCJloirLB2QwcGec8M+95ZewR6a/xFJf+Nt+pd/C0H1Zs77Hw3D67noD
  38.384 +DcXpx6i0pDiUNbflSgmiuPf7jKBRKtQXBfGHPs8JGNNQiQP9HE1RrML2Y+UFSWxv
  38.385 +VUY8/yDJPhVgvUJEMs57SwLJPPnIpD6tJbXQaeKpKJQPPsjhaSpTUVIAHf5HQkFX
  38.386 +kg/eyEvPPdrRlcCchi9YHfXoHn4RQYKJMLZkMKBHwrYTNP2gIf1YfX7taBzxsJXz
  38.387 +rUTSZTO912E/mfJu6nOroHh5qBxAD4kBPAQYAQgAJhYhBM7YCWrhIhaAwoSH/fd6
  38.388 +hr7BO/PYBQJaXTM3AhsMBQkB4TOAAAoJEPd6hr7BO/PYXiQIAK4abIzAL5A7xf9/
  38.389 +oqxteKTpA3K7kR/hgURGexwazPyJpajx1Trm9mxE822CjQcNa8Yi+QyWJoT5cPm9
  38.390 +cOdcnId0mmHe33ihlLzd0Bs7XUwlowYqCOEWhCFlgnwsvSjGHfsqEasznH3HEa8y
  38.391 +tl5mRvXfhaRkK2xvtureWUYwvxBiXryZ05rTqUm3dEGtoJ7ezQJFLrOMy40DNlq6
  38.392 +Ue7rw26MBa1dFw+OSt6eICmEaBym/swsyfQW6N7F5bronRIR/0bncF7C52E02lb0
  38.393 +Yd3M1BrJyj7d+d2ZHi4xArBJlKmCVBKnx7nnrcRGlt5RjSESIP0Nft/Tfar7Mcqq
  38.394 +0sSmyM+VA5gEWl0zWgEIAOEUgefeUVbPA1GrMuDrEO3dSSx1L3i3feZSEVnMZrVa
  38.395 +s4ut6Z/bQbnZpzMRIvb7TG9Rz6c0Paw8e2ilyLNUzeAF1Mkx5yvFFe1eQmeDZh2/
  38.396 +uwvvsYbXPw0H5FjYn25yXI/MaFWicg1KnOSU16gcbugw84+L3tKPdRVEYzBkG6nF
  38.397 +M0F61P7LAM/RAWbS8CpYH76EhIuFsvsUNFPw6Ne+2pYso3oDa6uBT1UcWLXLlGzs
  38.398 +b3x3HL1MNymRXAIBCmnvhAWEyAyAvrxNi0CMRLOrWuNI6yk7ORlvbxrhqRKab/WF
  38.399 +I9hglllu5R07kkLEmxxwGk2cSAYD8RT6aeR5SwC56hsAEQEAAQAH/1bUhPrwyps9
  38.400 +GFAwxdt8A5dn1ztF5+7fhrvMLDJixrqux3YavPZ07MmoPDbYpQ73yjhlrMCZyDMC
  38.401 +UC+CSUdZb2S9iyWk0UQS748XXnG1gLb4SM3lhax5rDK4OTDHPNYsWyYEWrmyheI3
  38.402 +xwftnbaWZXjAra1Sbb74Jdhy/frkm8Flfv/28m82DFUxAx8fMapodhGq7IhSs7y0
  38.403 +6EAOvhRTCyKTnx7bQKuS2MBEg71svdUWU/SV92fntBGzPoPNu7zGqjdmBPdgfAsH
  38.404 +UvhBsDiRZkckfHvozVXhA2AgafSY9RgRDWezaHEif3YTGb6kzCZL5RtHAd9LmMT6
  38.405 +iQFvDBT9+KkEAOHczjHRsZAtceN9o4M3KYBqLw/fDOIV4hqU0j25mEoA3eSvcT6u
  38.406 ++MFkz+81kZhlnRxizBno2qwMWF4JeRlZ8ybWgxMR5DLg/1fB4kJX4wfJXaptrEl+
  38.407 +Ofrg8WtzOX/6SXFkMKmO/oHt6i0cyLml7wBLbHTKOBTDrZN1dMmwUJCJBAD/HPnF
  38.408 +IXXPZauWTXxuyrBKcgRbor5y8i4oN2Q60wxHeGLnP47lD6fIlG50SQWjP8s17ek+
  38.409 +Motk78adzC2v1qKv1o1hbcPij9dC0vfUYCu1cMIhsE0FYSfC+08M/o4QsRt+Mr9a
  38.410 +NRZZjLNTlUTILF6RvJpIsod6EsgfLmP6pLtUgwP/Zy986pz3HOE0nWyI7FjRXAAX
  38.411 +9EOR/8LTVWc/qwdodVJVjgxvFC/tx64W0RhwTeTqL90uUrW1OF/ZaCsPXYXgc/3m
  38.412 +YC9U71mEO8mVh5S71mSgK8lrPTEH8xcTuzOnpg3Zo2pgfJyp4Qgs7iEBSVWlJVC9
  38.413 +sp0i2hXHZcsZntqctWpFG7QxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5y
  38.414 +ZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBBQtOSjaIe8CoootThz1+OCQ
  38.415 +9a7BBQJaXTNcAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEBz1
  38.416 ++OCQ9a7BcNoH/0UZFWkdZbMtQE9dJbECMEO7gDJhqudKiYoRPgi+7a0FBSk3QVG+
  38.417 +Prj10fFlhMFbQ3gSBjHCfAgWEIyJE+ee38vL98vPqJyC6isu18fjtptYsK/+rN9g
  38.418 +AHbOR7Kbfh9kkMuyZjB0mcAUPEHMig0hASZ3O8umtJZwnW2uwFGR1TOfJBrWkUZ6
  38.419 +vA2y60Q7Yir+gKucF6wa9Bc2EVwLyuIj56tNNlsfHsaWfU3A704lqzgxKjqkJ3S/
  38.420 +Zvcw7aRFJ0WMj1Vda3zkQz3lZxHRcEYqGukyEUXOxbEH5e1yDCeL7tsM7cJcyQ+D
  38.421 +2tdDrB5Uk/4lNe+4wZc7ZDc2bgTnPKCSStmdA5gEWl0zXAEIAOdDlt6GC4zlwjrU
  38.422 +SgmJJIaViehxFFCamo+b/Y3Kff4IqcCJJe8k4gal6J8b8ezDpQXFuN/30gn1vBx5
  38.423 +YlvmJDF2/Qo4Rd0eYzhPTkGyg1HBUlMuowhRtECmfnhq7aY/bLPxsPuxNfVA0vtZ
  38.424 +9FxPduqj/+32lQ/uBV536KElFtrNkotsFQLu+9UTakts7cbT2i8ZrWQG8xlqONTR
  38.425 +5xfqjZXeJ2f9i4DKN6ojcRvKWnqPBU/vWuk23CApFP3LuLCi5xdHfitf1kya+Shk
  38.426 +Q+5ycTqXThBe/NA6+h5vFY6PntTT1GVcaEnNFK4uat1ey4xRSNcvFKLJN/aBkzPn
  38.427 +0M70NcEAEQEAAQAH+gJVnHOMf8KZTExUJFdZDOyLsc0OEiiiTOKGTl6KFMWVuw1E
  38.428 +XSTfNuW0CEd4jIjpgdQ6IRdSrN+N8qszaaP4QbUwSIDb8qRBzaTYfmzbmKeAkkcL
  38.429 +GBkfW637jZiD1M202MaED1d/vBCTafsgoZ61FyP/yeIyLGJGfUOikHoK8gJ9TpPF
  38.430 +Wzi6yYySx7CltRl2rujTAkDM7KUVv6qgCV6SNNyZkydU0m0732DNfoqvJBlShLzo
  38.431 +iqgsUb8LwcvotYXQYW+bM0jqAX1/uu1eMEPNOLGE2M4IbiT3ttJ7IojnD+RGqyfF
  38.432 +1L1wEKSLJ93D0Q6i4G6zEd1UBdEegiuSz97wKqEEAPAA8KvtMXiDQPRBaodwyS9k
  38.433 +UboeV4beExLtHKIbIh13rJyuN6JJPoVcIFtSwI8ijiQx92WYxC8budG4gOym8qp9
  38.434 +awdb/Vi6KunzBXc2spLLVjVvSaQ8ds7EleUUGUGCTYhPwduYszVnlIEHmAqnkqbm
  38.435 +iERaAZh1/FoEt0p9HT3RBAD2rYds/GPWJ2bP+XD+xTACz1PPzw6fpcBXFWfHpYHC
  38.436 +qrjijpIBQJaZ8CfPqF1qnT4cZqC38aoXwvx5C1cspMYVrtFlmAP15zqa1hCxNs/A
  38.437 +vOyDfzZ14bdBOFwDVToXmbylNUKjCEcynFiEbhOzi4YwNFbQY2VKmlaDXwUj+snE
  38.438 +8QP/SQ4Y95i4AYJ9HrU196ClSgTULVYObbljFU/J/9SJUI7/xMNVAg+EDIsm8Kzs
  38.439 +kXOGs2v5+VzxbPEwCl/S9hPJStsEEEr0ZJSFNwkrUqPxuIUjUxYl2kGsrqlPId2r
  38.440 +rGcxgvMzsj+co3JcCESssGuT7V+oDv3rjIqec1AKny0vboU/a4kBPAQYAQgAJhYh
  38.441 +BBQtOSjaIe8CoootThz1+OCQ9a7BBQJaXTNcAhsMBQkB4TOAAAoJEBz1+OCQ9a7B
  38.442 +Nz8H/RxEq4NR8WOB/sbs4+qN4aqKlb+zH2EyHMtXO0GJbrQZCYnUfQWf1NVF78zT
  38.443 +Xe7NS0vWAd8phIxWZU01UfF2uPc5AY/V2FpgkeMoR+1kMm4L9wP5rdWSKEnx78gh
  38.444 +o4J3uKYbJL27pHRIPLswrJy2aWiUUK2jSWbWZV3fOzzTywrNOYGzWQxag2Nbhmje
  38.445 +HdumD0wwXD4RNviunN3cgNrpRv1wHoIvxpUfYHfbyB9mjnmDDJGPh5mWWa2fDlfZ
  38.446 +uXP4/8HZbhScWj9a4HXpo58ULqtU5Cn3DHs5HQbsm+MEM85BRHEFRYhkbU3U2kGF
  38.447 +oEPWX+59d1doeLV3dEnxolEAaCKVA5gEWl0zwAEIALf35c+3WYsMK/ZioVHECQIp
  38.448 +ZBXgXewPczKnPwY+ucQ2cBPdJpbNPmFSPoisuEgogl/Z/kGxJJBhjNvn08W8S9EM
  38.449 +UeQZTBMR6WOLE8ma1hyDgJGWlAUoCBh7VHvxquFMN/CIANwDc9ejVhh6Ng89ubhD
  38.450 +zvA5cggUaJrjJRDS17lCqtZwXZfGT+NPK4Ai0fjSSFRHOgzX/u1LM3Qw2oE0ex+g
  38.451 +9Lwdk4+y+/y+MqPwsUtKiYiAcMKRC+RaKTwjAVIocRCzFu7oJhN7+67HarvnxIGe
  38.452 +mRcf2RJvcpbcbzoSXdpOlCBX2GWgNIUgGNk9h/ONVu75braSkbaMNz13GtD1eDEA
  38.453 +EQEAAQAH/1Nn3DSSw1GDqLDRYaMQ9iaZPmuep+Zc0NUPt0atDIrVRXX0B0lKbzQv
  38.454 +VfOgHwJz/zvWuOvulI2y9GpEziHxbwwtgjkgcPmaXs5HISb/gIA37IPVGXHHBviW
  38.455 +faSd2ePAKwJtnrohBJWo02FQkw7Q5NESSRFncfgQzKYgQk9A0BYIyvWvKUoXLXJ4
  38.456 +I/okUG9q6QFHXiQ5yWNWj9OcBpWmlcbD7cClybpoHtRtAWvqhq+TZlxqGDayQ6v5
  38.457 +S1Nhemi1MzqYNNCYb1Uf/qPJuzPiEZ+MdvI7/lKhlZLg1GcCbtzUtWIrtBuGai79
  38.458 +ovzw9NgG+WiWnE9cd046CchpIOC2h3MEAMsTxuZ42KLV6DbrwHeawrbRpbhoPPBe
  38.459 +a6GfXx0plwGyVQSh1ife9QkMs9nEdo4w8NUCVhZfavWbyrEKRV+JkwBEaHKcgC5Z
  38.460 +EePndASgrJybxpqtbULwAQZumq2pBlIRfy4WQ6YYYUVuyS87atmaav1mSKGv1Mjc
  38.461 +634mFzezMnQvBADn6UcEFEDsKZ5VpfQtLehqAlC6jNtIe1MDQP9eJd6ol3g+ufYi
  38.462 +j64FO65L0g7rggiPp2fuCRdb+s+Rufxbq4aTDWO7b45OBS4vKf8HF/EX75Q1TrEL
  38.463 +MYFy7f84wY075cw4xtpBpz9S/DNNn/o4pX+c9iJLc7ebBCK+2fp4oR7hnwP+MEiV
  38.464 +tXy79HXDLWNogDCGaG+RwH22mRxJo4D3kDXjBYsfJ7bYIhFiY/mUmPGQWfgdTsE7
  38.465 +XZdqKe+XWZrKKcGOy8aYltRiOCHWb7Jy7qMv6tpcXTKDbJ8BNAP9JamMdzxcPI3O
  38.466 +9ox0AkryacfRwh3SZ5SkiJSrCvrp4J6c4mySiZ1CurQxcEVwIFRlc3QgUmVjaXBp
  38.467 +ZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBP6r
  38.468 +o2FethX+1KdyLHt9pda7H4GOBQJaXTPDAhsDBQkB4TOABQsJCAcCBhUICQoLAgQW
  38.469 +AgMBAh4BAheAAAoJEHt9pda7H4GOEF8IAIxGAcvbollx6NGEdleQ2uJlHu0hL9j/
  38.470 +LckV3Op7pP9YEwdA43GwQ7IazFXLmzOokvzNe7UH12/NA0lL1LhGoxh/jXkERcrt
  38.471 +ejw/skoVcN7CeyUDR8aLAvrgCp78iCdLGQ/imKfT7Qmy7KXTbhncUXv71GeiaVne
  38.472 +V6bv4RiFDcNt1wkOB+V0bYfuK9+EUtBFcJ6fgH+/Zag09ASxNvQERNC9ggV4jtDN
  38.473 +H9oQflGuY1dwna4v1Uk57GdI8NDPKFrIEQhvWeaH92WEUxAczPNkBF2CMLZqmvHR
  38.474 +CmQR6PBEAnM5DYiSkzbSnESV32FdI5BVHwY92J63fvvDL4iikrhvNGSdA5gEWl0z
  38.475 +wgEIALNKpv1ApSjIBp2w+5M1SWwIvDC7lnFZfTiwrYptJR44WMaulERerQVIyW+8
  38.476 +BSPsVkUX3jTRnPJQQgObz0aLnwILmOOb3Y9bnjbZPOAyKvcdKKpo3mYV2Et54/ZA
  38.477 +xhgoEFU3hhi5znHvY+Tdxz34+/C9jx5qpFPt2IiODG2sapAj4FArErXW+SvlGI7i
  38.478 +ewERYT04uQ0k6yxBjs7QTqojD9ZfagYQ6kOAW5zyUOLkY/G8pxOSAp9EBm1YJyI3
  38.479 +mS+7cfyYAtqmZyv5ft5UvjrhclW31bv0eyiE0z+q3yTNTurIzydOAZs+S+IdpdrM
  38.480 +8UnQCE6PvPHb+l+mwU2Aq6auBLMAEQEAAQAH/jKCgn7wWlcd2vdL5+P17CRaZaIZ
  38.481 +Bu4R9vwkkg9gZkeYOjJm9nA4d+f4NH+c6ZnQOBGpArnAn8WIJMDdgUxvgzFRURY2
  38.482 +T/nWJsFu+/5xQ7dwaIdxmc4Ks2+3/Cfg4a3mg4tuZAHNPsLMXUkZzcrAvUF6Nbqs
  38.483 +8nSOmiUGV6wCGddXOy4NyiTUHUa9kerDilAsLIvT2zyiXiWluyAeuACA1LO+9Nq4
  38.484 +K9JCo56Dh0g/wPeIxYFoND3cNCxjTRz2r1nB2KpE6pg7g7c43gfCFv7CJVRFpkIu
  38.485 +QmIicNfzRQRStP0/UVGCEkY8Pov5Ss5+2cV/oIeUn23tQm+CCitw6y4mWCkEAMpG
  38.486 +/xVpze+HmX0mRjVpfqo0CswdU819rUHjBu9CfigAesOEcDP6d9DVCd7KUBkCjIVq
  38.487 +aeL9VV7/Y0wc9ed/phmnMZoVJYeqbf5Tld6w6vj2XJgV8G0ZjYwbeZStISuLC1gn
  38.488 +t1rFrJX3cinpWuZT7yguSEHEMuj8sQKeGAaHUZ/FBADi6NZ2wDYZbD0tgWjbdIOi
  38.489 +Fb/4fm4CBRol4K61HmUJtwh8DfJtn6xEt08RTbYtWuY9xxUpC9909un6Xe4C0rBp
  38.490 +ZoeiD9zp1uvH9/2h1thtHAoUCk/rY5qSsH8lgexDGVqtvfig+o4p/wbY8UUdWvBk
  38.491 +AzN1ipPyFNIkfk8/oCaiFwQAwwnzH8AfOis6FfdS6y+EZ9kzv9q++WUPoXGLiAEo
  38.492 +90z26WJLCu5GnL2yZeZUPzOCbPU8eORK5czxwLR0BFqfwJmCQzClFDhk583vdfbw
  38.493 +7qNue1HR9IRmdwVb851ZqL419BXlx0zx0POI2tVzpIpUzExc+9jM+W3BWYClsjwO
  38.494 +xPVGOYkBPAQYAQgAJhYhBP6ro2FethX+1KdyLHt9pda7H4GOBQJaXTPCAhsMBQkB
  38.495 +4TOAAAoJEHt9pda7H4GOpdYH/2MI62r9RRlkDNcRvp+hLVWVGInXOHiKtm248Q5P
  38.496 +cGhY+Wfkuiywe+7KpHIzVmJjOAjAEB07nYR2mf5a2tRguB6cZ2qfNqnN8atECMyn
  38.497 +cFL/sGrr57kt09lUpSjGW9u4SARIYjGQBtEBkNKcrachjH/ZvnD1WnYoXYQ0ng+q
  38.498 +eMmtg7BDXySvn7Pflf9wbaSvgPdsaQ2N1hCST8N8dgPlxkE80aKT4xa3WKB8BSyr
  38.499 +lOORnUhbpTUo7xsjbNn7EZD09WdJ4wl7dOH/A5aJk3z9CMNmh4tYx8Gm2HCmL63A
  38.500 +Vh1yq12FsWjq/4YcBZy2aGLHDPuwZ/3GHxqrJYZ1RdpJKVKVA5gEWl0z1wEIAMZ+
  38.501 +rxH0qTTNdU2uDaW2CWf8XuBOHr6pbE55T58QETi/G/4JXn39wqt5TcqKe8p+aSqe
  38.502 +alncRFRq20iiVGg2jKPyhlDz5XsPyVu+UZcMa7HqwZjl1mGPzrHibLfNi2TnHCR6
  38.503 +Sxpha+FdsJhk8fkbTRPWgSxeQ0cYDMATFIxMLavk3GJ2uhqjfBKp8zowrOxrX2XY
  38.504 +rpXKFI+d3RstAdIo8sJGvr5OFAZ06vqUzlE3Hey2ux+zRoRp2B+MIZuFwE1Olbkv
  38.505 +sct2yxSVCV6FbeG7Xoo3Y0QeMLhNg6ctBWbo1nFc1SKgc0+LYf56yNUhRIjm6EkO
  38.506 +XgJO/lZp3GGz422K3Y8AEQEAAQAH/RFlA6mNU7tar/IX6SlBm8Rpk3+Q86pzWsLr
  38.507 +vZmrr56rR2Q1OlB3NEqQ7aDCDwQZR3+3yeEdvOfa72QyRDcCZMPEmpcDMJ6JV8ol
  38.508 +klfW0Pnn9SxAI/qBFDTMKgksxuTs8y89KlIMVzG041IPh+bzyLGO2ttiV/9QcQ7v
  38.509 +UnMoWoOVefb88K3hxFQpASyTEij8iojhEgbawbVjEkJ0ztqmchW5wrx+MAlGX2qE
  38.510 +zRMXH3gLdcdwZkzsnk6V08N5C+6rauiWIFmQ2l/sWzyTHWF0dh3XwEGvmn5bCzLE
  38.511 +Iahrh8tAhKP9muW3EmdtyW2v4WuJY6u2jgQ2asRrKqDdlmQTt4kEANIzRtB2ohrq
  38.512 +jbsicO8Dk9QT9szz/6B3XtZWm6UP5XTQShO6CSYDyNTG5QBm4o2myF5/VIM6Jj2D
  38.513 +HWWMPyzFqa3z+F/W/5KjSWhaP8pT9r3RQZcwhZTUVaCPpgjWWkmJkJWkMmuqY4Qj
  38.514 +mfZuKUDoqqY1HprjN904NlnoWfO01C1nBADxvn3dyq0lbgh48+/owhUs3LaJYoTt
  38.515 +0mR/800oGH6y8cN5EwMTo/393nNAvLqhLKNbnPeTml5S2Bjl230Df9P3IE2O7phX
  38.516 +loUWCSrBQJYptZX27E9MPqdlyTeUgpi4AQkXATktOsl3iKEduisoq9Nsi6tHHDBD
  38.517 +Uk/fN7wyhjaNmQP+Njzi1Bu3k+CPKzt2FZ/PjTesB3U93nH+Yct7ViZEJrbfQIVh
  38.518 +EquyIsCH7QV0NTAnvOOsuYls6hzK5JiDa1pMaA8x31El8Im5PYqjKNZE3SfWRHNt
  38.519 +yd5QNH72cB1rDtdxEJ3p3Fhag1uP8a5DjGI1ZdssSmzLSP1qSs0LsGxR5VBCy7Qx
  38.520 +cEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3Jn
  38.521 +PokBVAQTAQgAPhYhBCpmJ9rOPHpXYudMuGO5uXMOOlpNBQJaXTPaAhsDBQkB4TOA
  38.522 +BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEGO5uXMOOlpNWKUH/ja40aq1nPlk
  38.523 +g6yxNIErVU+q3g8K9YSE+N83rYFjLRb4gz9qRJhDIcmhWrmRNSZcRgWteIFI+L75
  38.524 +iVVfLYQo9NlBfJR6eaFJiMpeUYCmewppv2aj59n739LRyws+TN6n5JG3XiXHo45S
  38.525 +exbqU32xFXFNcJudegawHLKUJ9FYr1tegnkZB+fAGp7CpFeqpIgCwUrfXV2GkJuh
  38.526 +LUtsMx/sx0jBBwvWTI07eR64+wb052vuYgTYN/fNfBNG3lzIVrkFPkDnzm0dWIut
  38.527 +Q7kLiawoO+ArVuGtmwrcFUm1y6bQwQVftgNSdC2Ngbs8otWU+SnvDXrsTMDVkjWw
  38.528 +yZiCAoinTcqdA5gEWl0z2QEIANwbK+RFBR02bWdejNlJvAa1XV37iq+jgdz20hbv
  38.529 +PTpXcyx4H8oYBwksE054iDGl/LdK/kscF1ItvdXSpPEbkxJv7Q4gyouk9+3sr8MF
  38.530 +Xa4FusfEisSUVzSSmYzVY0+GNjUy9fQURryhUQRp31PUetYEmrQ0G2PKohxzvWcl
  38.531 +NEfbK/KUjA+I72o4hA/AXwnaT4QbIAvBbl4YjGpr8w/mhcJ5BQF1ny7aTCgOHx9U
  38.532 +SNTq0q5wxm6wOP+nMpArMthg1rJg/95IdjcGB0dhrIfH4PXGAN9T5Zg+TUY+OMJN
  38.533 +1f2/tT+hBOKhQblcHNKxCPPbS2lRzJ/+BmMhAPbzJbv56o8AEQEAAQAH/0TvV5xL
  38.534 +B5KCINqekLNe9f4N4FuWc/WVWo9HWD4pmH4EtIQpbR9gzhdP0A4kDtep2k/Xs3P3
  38.535 +rNAmlk15BwKidbnxBwgFOhppROMl3VhRfmkJz1lQk3uE0Bkdjuy+Sje2W5TmzIQw
  38.536 +s4TRayvcMr8xDXWpBIDKzwc+h+4sS5YZ31lfVPdQ8swSt9S08w6bA4MiNiYwdUqp
  38.537 +R4d1qmu/3Wv/IPITTvzW1ezPqUagrLtS4a857nnmZVh0TXIZRO9deK+5J9JPXkZn
  38.538 +MvqLLdsURXGAdJUY/IoM1JdvPkQM8NalAC+lSlxVXT6zuXrN4LEqYQIA4l/JlukY
  38.539 +TFcQVwQgECmc5+EEAOKciBFjHtyZL4BHvXnwMLI3SiJrjUn6EMNsebojZwzddebZ
  38.540 +gpsrZwY+zokCrodiqMl07v9QAp3i1C0sMQecC8BSXnAtcJvPCQsLr/QSYTifv4c/
  38.541 +t2iI6u1YI9AyseRFYwQFA9+XfRGNBZu54HSSw+o6CZcRZorvxBqPe05i2wdhBAD4
  38.542 +pqoaQy3gj3VqFaaC3dyCpeRip/XnLhQ/FkBIxx/ET92IIZpj+TQGZ6SoRx7WJ7wM
  38.543 +yAXuXzud3Szu8em+A2304yqPEe2E3Koe4lwfeFbpBd1yHvYTQQ4FImczo9XBYck1
  38.544 +FziOQNVZO0tBG3hxJxpOT93LDC3JX3xt0PbJbUZn7wP+JZb0ljA//VNQoV3yghHm
  38.545 ++yJla4KTVilZWRfOyh6Ys0OgQENgWaHpEAdbdLMcpu7Bmspm0tXSnqTlC3X+vQXO
  38.546 +VR2hwuZ8nHmjRl17zdW9WKkxlEdXo/lTyAkDMY/kbcCGHyp/GOXBC9C6x7ppjLaA
  38.547 +82Ie8BaXWA4RrzVrlKxUbVI0ZIkBPAQYAQgAJhYhBCpmJ9rOPHpXYudMuGO5uXMO
  38.548 +OlpNBQJaXTPZAhsMBQkB4TOAAAoJEGO5uXMOOlpNU8QH+QG2AnqGe0WVCTk7yG+D
  38.549 +zETgBUiua5O7tyzWMpstHgFs0B7f62+AcziMPwxdtvkpU97IvEZIcrSA9otdrk7w
  38.550 +6XoIqzG4nlHs0LZOVOetuA4ohXP/SYeK/Srn5zH8fpj4snVBSvMfp5xoNFobcQMg
  38.551 +XjZnFICTVX/Nq5lz6ovaclcAzgTp+qAk0wmOfFa4t4gOg8uCru6RVKdLei68Sheb
  38.552 +l3T1Ch/gJzjCsEcQjQh7t9fpW8pUcDfJKaCLYjJncyKoNOphRbAZDx2/jPihQMg1
  38.553 +Ok+ZTDPALB+RXU76+LbDu8F/B5uLvTLqhNb9ERJ31gcOoexo/F+L/LKBX0iCbmdx
  38.554 +4FyVA5gEWl01oQEIAM+fiDqAWdm+q77FfAO8Nd6AcJwTJl850VT9ejtTLwkOQ18B
  38.555 +X3fORJko23Fzz5WOsHiNJDce6v2l+0XvmtX/kqPRxH/XhZuzChJXkS5SE86XH+5y
  38.556 +Yq+5XXd7s6X0plBvgYmEDj+zFZgjXEUYUuacKWy+e0kbK7RaQiqSyEFObtTa2vRq
  38.557 +bRc6WAirufsjiG0BwCg3RMB9ffNd8sA0rdDYsTMviJBfck8aap4K/5ROZU/eB4pX
  38.558 +TlwTExbMkK1cyGMAJHZ1O/XA/D5MLkqcIbu2SIpM3vZcX+m4F0pl/8N/OKYLSO4r
  38.559 +u6v8DnhEMg2NpENyGIPHDW/sHQ2sID7Hfyl6m7UAEQEAAQAH/R6cCHuHfLercqqX
  38.560 +duceElsRWIjKEfgsD/6VuDWS1/Zf0fLpwudo05g4+9FIH6yO8tlzBYnS1xY6KEdx
  38.561 +QcSW/0mDnZKzdZE03iFCI7dOhnkIsr52wrHhhDQfWqb24KYvKkvZ2jft8RsS64GM
  38.562 +SnyRPVI46vgmN1VJkUOxjDCEnbZnobBrRE9YYFCDmHG8fsDMM3kka4A089ErJNB8
  38.563 +lPhEiw90B98O32BbDYGqI5nWifAfSq4yETWW8oZqVEbGQ0p2+oKiGZbwI36dtDSB
  38.564 +Dk2gRHbr3vhxpfvoIQQ1bfSXOazntyRNI3G2RAjJBmYt9MyG8XGa84ci1cgWaj0G
  38.565 +2tYHYqkEAOPp26j6/bmHJE8eBqgvnDhcqYO3r68sj7ooAPKJsAFWMzjy9jOC4jW2
  38.566 +prceksfBF6sFn72vebJJ9lH7AbtU0UxqpPKKuxsA1/8dcW8lli33ULdrZ/SvscR3
  38.567 +uEhdPPSGKwMRDgGy2qc5/0S7Gsx/E/ZLrjl5prHjmIoRxwYhO6ebBADpNY+lyH4g
  38.568 +C63dE8ZUGNxGvU1MwVwkJFzEgDaN8rQ69wc+vCBRawXDRZ6KK2H14Fk7QOvvpLMF
  38.569 +1NDf3ctIz2Gi9ZgcPfzcIgaTse3XqYFJfiaM2nped7QOj70vegvWUtEQLu1MoUdn
  38.570 +lhm1Ob7OX/TXVANIl9TXWQV7e6onZwqG7wQAmnznHCW9Z0Wy07OrbtjbsC61n/xz
  38.571 +kulU6ANCE6H3ZYm0l3/9hzulxv4q9j9xElB4WSINtYOuJfs+Tgyo5PG4YN27HbTB
  38.572 +j0Ko7TxFDP8ea1+A3pIeoX757HbOStIbE2AJ+zXRQlAChPIc+ygJe6OjpMb+bVgM
  38.573 +oiPq0Jwwk6aBr0dD8rQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNp
  38.574 +cEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBFTIHdH1N0eSB3th+VgZdUZP+HKf
  38.575 +BQJaXTWjAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEFgZdUZP
  38.576 ++HKfL7UH/2r/d9M8JRuXVG4to0YBF9nhtL2wG7cl/5NHLRQ+91nbqA07/QZziQs7
  38.577 +sq5ot2XKYC3N2NUmIHDE3hMWzM3dG2plN7/xvtaFdNo41HtlnWNb+bMKfj91bybu
  38.578 +++2BCoRfwWtHUwlkjYcXF/AxiA46qj6UmBYEcEPiaiLObgH0TJ+D8Xo64UP3c36g
  38.579 +s6sFK5T068XQ9TYj6YdNA62YOukxoc/0iaVRAeKm7cnUcCpxoRjybeo+6Q/Ncd3y
  38.580 +CN63FY3kxxeHvkYluC3yNWbnMFl7Mmh1GBXx23yVfWscor4IkomX2Ue00ptxut65
  38.581 +reUxlXvDq4UUX2O54DVQMeJUCzpkMG+dA5gEWl01owEIAK+9gJUrodadwHVXDIPo
  38.582 +sjgDyVGSYXWMxb6ajHKZLc1Pb4/K7TNGo0Qo+VtT1TepueC1FHHSWHpjgpV8TJlU
  38.583 +FzcPtPobZ33jLPDIpolojPamXXEkfRp5epQ/0ppR3MYrzRQDS5Z8mS1lpD/A8jrQ
  38.584 +VmCQMXZEJzA/lDP+oX2mHLvA9CRoRUjoIzpvQvAqKe/dLDmpfjfmc2I3W9cpAiQM
  38.585 +7gyGFr3Hbpi5NCde8dqC0Zvv7mGQaPSLYFsW/fXAlhMiBauCZ5XUTyG9dLmIdUW4
  38.586 +TAVu23NKoAdsdQFCmAJX+1nK+cGAw3bPdDGnLCmsFtjWYPEc9JQc4Brvk8bAOpk7
  38.587 +kbUAEQEAAQAH+gLNRqDubHGR27fLoOQO3cY4ln8SQZF4+hD2i0A4zNKWwppy/+DE
  38.588 +59Rc+N+Ev/0omGWsWuGJlC0Sg3LBrfeyehKybIrye+dd4auEkR//clUpUgSkv64t
  38.589 +xUVNII96Z1QwkAGZYx0ZfsQ6IKa0gguGenBjNj6rA3KDjuEZO4YNjR8KVIshB++i
  38.590 +w8BpyJvX6XvaWN8IUF7JA4ua68B6SGvYLtBIKihBfClXqrjqp2vyCdqH/3L0gT9G
  38.591 +eNo64fAEGUyaXrjrbwaCwAkQ9vdliNrFl+Yzewq+ogDZbf3GBVfKK0EJLwYrQY3g
  38.592 +j4zoD3hyT5AI2QhKwqM64HOZeLKXmaR/w9MEAMewyU/tdO7wKlgOpW1A32lHdSVw
  38.593 +TKy/U6CA/fYDlXyG8uRVBSNXEH9jQYC2UWl37p7DD52yoL9O3zrdyNYDWZ7HXBQs
  38.594 +Py7a361zx9kbAMtsPjur9kagdc3ePKqneNzz8ZaSFWO00veJJBN1u+IfUWJESz25
  38.595 +zQiUrNisZC4KP77zBADhS8umWMUuIl6cr6eND771gvH/4eItpTtbVovmxU+2ri43
  38.596 +prX65dYbVst7TDW2HpzX+h8GfKoaWqB+ZN8nKP1uQRdzruJbPvfRiejBYmkdwZgM
  38.597 +OrD9yXDBx6bk274GkAmw0U6LQKViqCf297Q90kY2JdUd0Ou0pH/LMyX6++YmtwP/
  38.598 +RKR3+Gl26+lFTt8Wxf/9UKpHwATLR5Rrs5rbCKOluq87TDFpKlr0gRV7KUvLGwFp
  38.599 +eRXqGOl8Nqxro9/QE8lHhH5a64SvTMvLZ7Z5uKRxEPJ08CU+ylBFHCMdzr3N7W1+
  38.600 +/rX9GY7SG3pPiqivsUbaU8VZgZV8PxyzD2AVRgU45hRLbYkBPAQYAQgAJhYhBFTI
  38.601 +HdH1N0eSB3th+VgZdUZP+HKfBQJaXTWjAhsMBQkB4TOAAAoJEFgZdUZP+HKfjowH
  38.602 +/iczZntv6yCeGn09xWPsLpgafF4r6rLr4FD4q+XRerDvHnHNb87fKVEE7iA0YjR6
  38.603 +ZeRo14Ps0F/fU4nSsBWA7FzPbPiMmW9Ex9NhxXqSEmNt82gmkqsD7jkcjqXzZr+g
  38.604 +FFwOt8nTRAKoHjdVWIyGKPUorigSJqfwsMTPKFjvCEV2F/QyWocpBc5Z5wp1nI9m
  38.605 +rWKdFK4BVhMKCJp2LfDwZEcyexq9XHTx6mpKKT4jOkgr+7/ubfStlYycQdOxrbKA
  38.606 +UmwyJRuVExTYu5vuMQQ8MYS+hfQX1u/wczMHtBIcfGO1EKKIlY6EG1Iza0sXFUvJ
  38.607 +kefytbDzI0SRWnV7G8Qo8l6VA5gEWl01wAEIALPtHDY3PPmF6v2E2S+GwjFQgtc7
  38.608 +EoiZBFE2ohZxM3N7k+sw5bAdwRVtivugTgItp1eK9+VkJBiGtMbf0e2AIMOrZO7R
  38.609 +d2yyud3C/vbsjDZsDpsxqQ+jjzlfaHd6hwIeOKrYNtWEQi1FlBA9FK0ho3t5N1/p
  38.610 +ECRSh0tKhrXr5gGKuAmxJVotaQYhXx0ymLL7e7wNQ2FfMHW6za/ywU3mBcjoNiOX
  38.611 +Du+xwwKOJrdxtMFwxzahOX+nfGs0oUACRurHW549hs+y7N23617F1TPWxd4DL/8M
  38.612 +VVMyopLqJmZnBt0TvzDjY8Rwph11dQFhF3Cvstf0op0vKa7QDuzmcqM9lbcAEQEA
  38.613 +AQAH/Rb0VBoSmAPZcu5fCXpHvfSeqeKdlbK5mtRlnO4yCPddt7RUq6j5Us3SCN4r
  38.614 +SGh8vJGtmAy65uP+I4gPu++J3iQ4dIsHTC4g6xeArhiAey7iQEbKYiAtpLMUGfbM
  38.615 +OfcqNd6N8Qjyc6Lk8ovTzxR7ayjwgQEKcdXAdaREYMVK0DA39Gu91YB0MUZlWm2i
  38.616 +Lc3PFtp2NYfYp3gGQwgceORibsUFGtiTLFDKp+JxKEVu4W4SW3TJut+n4hD5zu7K
  38.617 +EVl8Puv5qpynemDn/w8u6ki0Rp6+ABwrq9fyz4OQPs9Z+dXNGXZlCDxxZJAYDPps
  38.618 +SsAaMHP1RifgOs9a7aTBXy0G/tEEAMXpckIjn4XmV/sGl3hQytT1o0V+XszdTmMR
  38.619 +B6Fe4D26AHgr3P1ZoP8aWt14BntucUoaSCob2Lsr2QdJqZzF4DiF9O0zPxaLHx8H
  38.620 +zlvuxAKVDYCaQH5zUB6IgWoZY68NkxTNSevOsTpi3CfU6Ro3Km1oOJbWfulsnQt6
  38.621 +P3jHWTiZBADovETZxho4KfaeoYiO8mAHRGgX+MvOxPs/1eTBiq0i+xlZDzXkhF50
  38.622 +NFjNaLflfh16gPQ+h8LSfWzPzTnT5AEenijciHS5YGTuiO/GMdvDKXcNWzBUDdKs
  38.623 +BEr2jJ0p83stRHILILd1uegMtSQHQWQvuToZJtlR4Hk4rBeAI4iizwP/X+XZfZBi
  38.624 +iMyROKUO5m310DtWOu0zp2M2RkuDCwkurYBpyc/AA5rG8cxwT7eNL+GkldghuFVb
  38.625 +5PWPF3OCC1dId9ClmKV1YpxaLCnnihZNjYy9DrzTdaQ7QveqSWqCfr7sNCiDYooT
  38.626 +dAOSY1Djn5+QdBNFClm3P6h1D2bUo7piZts/BLQxcEVwIFRlc3QgUmVjaXBpZW50
  38.627 +IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBNRLLWZE
  38.628 +D38Zcro7RZiEXHo3UiiKBQJaXTXDAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMB
  38.629 +Ah4BAheAAAoJEJiEXHo3UiiKgywH/jA3RGu85kOoJvqij2qe/Xn+VEg59Hn5A8jh
  38.630 +5v5mM7sDw7JCoBeeSIwL7snGJJ94kjQv5Phqgrg2UKcIMDEpOQpgmjRF8tbevS7k
  38.631 +cQGBBVbRc4qJ3w5R4Epd3NCHdfZCxRuCGuXS8mNh7QtxbJHRBocQNGTto6Mp36Zg
  38.632 +u6fU40mO+JbOlEDV3Fm6vxJaQ9WT3Tr4Bvx8Y7MHtaOQtYjXOENhTrz9rJGCjW3e
  38.633 +MhJkpV8v/wQAJufrqUiq7VMlIt9nzyNArCrnG3xHSKWJFA6fOFBioi6TEGmahkwZ
  38.634 +Rdw0pkP+4FGhj/+cFuWWEGsw+UFOHlhEKsBY/HukIogwtErSpkudA5gEWl01wgEI
  38.635 +AMmx5C+2/+NjMpxHM+T47F7wKOP75do4SuJrLTgm/f3m66eqV19LwEfEUDTQH0Gw
  38.636 +HBUUnoW1G9HWTC7ZiGpA/dVb8hrKyJDVjBp1YXT7oFg/O0UqwWpnQuiRFsQ4O1Nw
  38.637 +3wtwWHBTWrOHszpMKWpWrE6FTpdpublPLBmlyLpYIblvnskoK+WpJErryIfeHIpO
  38.638 +oBHhlCt+NEeOwKY1CSC3p1zd9cf+pUdnA5aZMRPIAq3JYJMz2FkufBFicNOcNkO6
  38.639 +TxEovNg+i8DDl/Ssjvl0KahMH9BrLlfVXLoWdRQG5CDXBiSmjfa4XVF9Q9/+nFgn
  38.640 +CLpVxwqK95H9qZ2Vyko8Wy0AEQEAAQAH/AgW4uyI/e1cSqja8DlkRHKwViuCrF7a
  38.641 +uCIpo0gnxDMdQmFYoyV2z9DxDjh4CnDjg9TSnWMGdwWs/yQ35FFCpwuaIvUxIecx
  38.642 +MWvUPmLnPrCbZKCrDNPcLWJPg2a+TJ7VnZSDXoCuzyn5LNaPPG//5uxFS3gmLOVC
  38.643 +SCYFMK5Mn5mkzrJ0p1orCa5ECaCNH9PlNm+ALfBuH4oKTFev8sWEn/S+kmQRe+UU
  38.644 ++ZsNmEfO7YG2b/bIEY/ZkmkJy6tR8nmoDU+j1rxbhLjMZOGxAj5zNOQ5oGalKDcE
  38.645 +YYKMFlnIc4OAlrOXxW82UYOxUyI6o/3JqBbgf1/op2YlpHDAAkZizIEEAOBtQq41
  38.646 +l5S2nLnLUWXFbpERQr9+Ghj4kyWTQk5yuIpP/+JSCqfaqrLVDUxnhrusmvP6ugoE
  38.647 +/zD586kt7/xxDdqIJXD4m2qCG2Onprb1uh0GV3EzUOGAk/bim2VsyVLJraPneB99
  38.648 +uW+VGL36J3efJSeOchcFtQx6c3vK857wx6DBBADmEfC1wV3iPLr7AW5vq2ccneaE
  38.649 +wUDaYSmixQEyO+jcih0HLOt4uBUe1sJBWkcXHy8jMB1xbEbWWqnHyDAFEvN1ZJ8j
  38.650 +iIrShQNMfrRU1DQM+uxkLaE0VEzKT4JgKXm6cfvVDHyvVrBCzvY9xbjuCv+mx88D
  38.651 ++0nJgqtIz7dyjf4pbQP+LgAPIjuG29vUQk3YLNiYuoXO76HzmUwmjx+n7yVYGWgg
  38.652 +ecvX0xaicQVBkzdZr61/wL4PNbJVFcXyQneB5d90NBaE8Xc52MaPI8G+m7uNP1QL
  38.653 +MxSPKlCcoC9Hj4eFLFdeQYD9E9yJJGdWWW2GC15zd/RqfLE0IUukXf3iMwI4wro/
  38.654 +LIkBPAQYAQgAJhYhBNRLLWZED38Zcro7RZiEXHo3UiiKBQJaXTXCAhsMBQkB4TOA
  38.655 +AAoJEJiEXHo3UiiKRn0H/3bl8spXmLbKX/KazulNRLrU3HOam5MNbA/pwkzQ33At
  38.656 +tULWkOC/lBlBfjPtkLJrqidLf7ptxPG059sZzKU7TPMuYibPolzcFuBi0Wyx9cOk
  38.657 +ssDxubtqLEo9fAqn/plD0XAHHlM70O1pYr5b+fHJbesz4BXFrKW7mdtOso5XV7oF
  38.658 +GfO2n2zruwyAQP1E6INHISmbUdskKPLiFPIuzYDY2QOUYOj1rH2zeKnlAybKYfmO
  38.659 +/UHitRkOh2NfRRLb3phfDcRvxOCeXf3pHSjUVGpdaMNr2+8fexxdTIT84ZqIqmCW
  38.660 +opI/Tv9HcME+KtY3t6YfuQMoaDwjJIP3mLyHf6hPUxyVA5gEWl02NAEIAMIxf0qz
  38.661 +ipLSYHbIJzAwrMsZLJgRZJQb0deQytqJMKZsvyP8a8JusvHM1SF1jT9lOvkVHytl
  38.662 +fer9wNlXxn8gUQD9ScvWcoACZpOW56mRGhVxVVQnWuZf8a7sbktw7JZ/kLaxZ+E6
  38.663 +W7z9M0BWnYD62Hi5+AAz8FZG+sXAcU2waZNWCoFj4RqOJPB9x5ebKdOcybwYONlV
  38.664 +AyeV9nqk/Xe/DVBpsA7/cbafHtELQJgbAsqVWeu1DoBYEKPZB5hzWM5CHRFx8HYX
  38.665 +c6CsA2+RED/NoH/fl92YiWuzcsL14CiXNmcLzKdD8khyypgv5UA84XNnti4M9uUS
  38.666 +ndXB4lbx2V/n0MMAEQEAAQAH+wU8KiELSo+y7fEua+ca3R960169BK39AADpfDoo
  38.667 +zI1fYOOVp0DzFMksyyo8yPuo8052YH9PVydPUf4p9C0yxixB2P1nQOfx1O5PPhdL
  38.668 +3qvLsiiHV4ijgPYAC5nmWP/z8MwKLKyJunqxDwZLpZ2QUecTRAqu5ZufqbBMg+tF
  38.669 +bbPLVFMdDlbz20e1r+05HGYSuMJLwPqfH+9fjUAlx3yi/xE8l93iZ+r9eFTqeVsz
  38.670 +84i31AWbmHwD+uthz1IrO5L55ifTbPlu/Orc5UqFZId4fSKF9XBxyugvQUYhcs0l
  38.671 +Jla6SExjfIIhWE30j5uNODUVDTtE7ew843LDXfBcnJtyPskEAN4ZurBRPokER4Ps
  38.672 +S4A4CqIreFRz/gIOMI4X0KW3nsML04BZAQtoSFqGkOC2TBa45iCKKe+FXPh6yNgY
  38.673 +JAc2XKJOccJpJTSdsYWZTDRVS6AJuRLs+eyjVxAU1sixWEGrVRc8IBcefO4IBNlz
  38.674 +qTXRYaCHhubzvA1///0wOOJUuoq5BADf1VWYbB9rE3qo7EhMruLzIApqWh93PlS3
  38.675 +Ek+IgUOa55fTm49g+2e+9RCp5/YEOHn3YfHDln3xexaU98+7bfZ4Mu4YpeN3MXwz
  38.676 +HpTCPm+crdtPbhHaIQWkBkcgoZHKi8XrX+y8h0fieMIj5cf22SSkFe3EM9SHGcdY
  38.677 +HQHBDHgJWwP/QN+g7ZXgqPNwa8kkVcat3kACqS+EAs5yEtQ6/4OVF9Prj1RdeICy
  38.678 +mdAHdfbF8D7pjGwg/JoqK26wl816zvGmmsl1m41itAUBv5/xySo2vBK+CKAVcu8f
  38.679 +kCg8Mi6c87s+qbNs7vtw8mutYeHMTTg9VhhAorVESusDSxgQ/2dvLfhEL7QxcEVw
  38.680 +IFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokB
  38.681 +VAQTAQgAPhYhBLwTTmTPjEfBVh6+T/P2h9zIQ4IMBQJaXTY3AhsDBQkB4TOABQsJ
  38.682 +CAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEPP2h9zIQ4IMvF4IALzAjdWaFTXQcHno
  38.683 +kY7o5otLJmOatirnr3P7fPQbhHgeobXwhAQxQeq9OTPzfN6LVL4d9pNjARx324N1
  38.684 +2bks0kV37oSeBeoKSkHhKwQpeQIOUA6wuRdm4Ka6Nq+1wRPhZYlRwCZGqZQL7xMr
  38.685 +wqLML2bI1ZEeAHum2E0T6mRxR3dyr+Xko8E2E+wy46jpbTOUKa2VrxSrjqESpbGM
  38.686 +XVGtgiJ4ig2fL4uG0aSlpl3TkzGmaRYwS53J2MhlKsMTVb4EOg8zxUEiGkCqoUAI
  38.687 +KIGAifDWYpTIuMJduSIIPBf1ITM7gBlI0hv/INIBSejGOEoK5/d4qtYCb+5UZSvH
  38.688 +SLI/jridA5gEWl02NgEIAKsjvnOgFetfKaRo0X6wc+mxTXEnaw+U8+LG2mBz7CTF
  38.689 +DlcyLnjTR/Dky0av3MLQ64CSBe+OLp/0SqXTAMxodNK8Xx/sut+MxrImi5k1hco3
  38.690 +G/Uub8nmCdkSrAwdnkOwiGhGwZJf9hyU6djTOZJ534NxNIq6X44Z/rwGUIiB1hMe
  38.691 +r/uzXVzentw1dld+sYvkjOp6fJu5Xz5wwiFFLHDeRj8cxL8HpWmZGkWgYAo0HKEE
  38.692 +3cRI3knJBZounmX+29kFaks1/9ulORveS/qf3ffnhigeD2b0Yh9Zkojl3DoURbel
  38.693 +704wAfcQl/CfZR5H9h1JqxjQ4YEY26s2OKFbFX0RQb0AEQEAAQAH/A4bQiWRunzO
  38.694 +OUZ+BVamAMfwf2umTiLYqkm1DmcI5xwYyhfR4RbAg5uNoFvRPycnxWGxp5+ZXqp8
  38.695 +nnKQs+4lZgvAzy54eubWWcJxfuxABykl5b4N99TyizlDWr8c6eC2emft/SKtmkG8
  38.696 +3JGsx4AVX6EcAbK1rg6ugdrJwnWeDiFBMcSo6EjImy237emZSfBBcgfE1K7ZmITL
  38.697 +8jzZ1mVY7+IIQo+7Sy14FJ/pWcdEq+tlMSmdCCSeWvGSoxuWeChuIQWTuRUzvp5V
  38.698 +IXvojudwd+tmml/IiN/nsQApaTvVUUHpbV/m/Yc4p2MGYTnMbT8Jszl25k/PKmCn
  38.699 +yHd3O4wwlxkEAMm5iIAEbH478190WuIC5ObXC7JLQyxvP60hX+3PFG5eXD1OqMa5
  38.700 +nLOwjxmXoj3uPhHVU+e20I2dATBJK4vLAzK5Hipvw0Q0gWcqLCkap8qRxlXQHlsk
  38.701 +lg2yzX8Qss3pcnQdeVgOMvuj7ejPTBTRlBsrK9YQOSNHBhySWgoWk48TBADZL48A
  38.702 +hf4ebkG6T1JGUNLN663kZNN92zTrQjzbV2sBWHO6txVHGToAygzuFWFJUoXAVQaC
  38.703 +S8R0lI9+sDpZrfu0B8Yyc4VFRfcDqcekj/A+My2nR0XWDWiVDPP/RVCLpqVALJ7m
  38.704 +p0T8hCaG0hSpr3eonFFdZEsAhvbnfdDZMcl17wQAnBcB+BPOjoaDgLkLZ9t3vpBQ
  38.705 +L2hMZlkvx/Bpn/M3XtkRuE9gmh1xBW19MmxnOS//Oj69zCJDMRt8FZLWHMRGe5R8
  38.706 +YgNC+OVniRhy1RNNKti/n9M3q2pfjXbyuk5x52y43u9m8AsdOfa/fVyRPiKNvbmf
  38.707 +gIhdB5VtgnwuiPAEAyI0KYkBPAQYAQgAJhYhBLwTTmTPjEfBVh6+T/P2h9zIQ4IM
  38.708 +BQJaXTY2AhsMBQkB4TOAAAoJEPP2h9zIQ4IMFdcIALqGBDUmSZzDV69VM9835cyD
  38.709 +0nz9Uu7C68nwkeVpW4koo+BbOiirOek8DH+knV3B8yhFpw1dkWiJWBTYinmJ/sba
  38.710 +3J7q6Nk1s0bmJXjJCtFBaanUncY0ybBfJlu9sOuzWXLxUf2CcK2iGebgzcaeOUnb
  38.711 +UjbrFGhp4oKy/9OsKX0YMd35ahjzvE2Qi+qR9WCIfVk9vvRcD7dhBHCsOaUnwThL
  38.712 +uIZ86wyJkRbtDm3tQyqrwB8oS1aAgBEvtZVRud9xwOAA4DmWLjBliVebNkyl2fLj
  38.713 ++oC13vTPV2D0MfD61w5kSrkOn/hZsnzLfz2J8Bg+GFej3myZ/+f8P80Ro+kidYWV
  38.714 +A5gEWl02YgEIAKzVegNE71UBwexUA0zPnBbvmqh1xu2/IUT8oNozI4SAvD9CcXdk
  38.715 +8nYr8ExNM/XjauIxA2cSUqZP7jPpEhHogVhScy8b8qCcIPDP0Php0aayZ+r+s9P+
  38.716 +fotOMnFZAvDFrq4LQhO5TCKpGEyrVNyYdgq6chaIpnCdz2apvP7QPk9rqbztVSDN
  38.717 +fQkszawNvGnhhpBIfYroCCECMxMKiNF/HUVFXOpf1dWeiwdqE99fc31fWbBGR+ga
  38.718 +jdMIIuWy4gF1RPi2X2id7OZJ0aIDsVznXoBFsmWyJvsBpxuI3+6OZ+se06rXp8uj
  38.719 +SKsJjg3ce5EpqnnChydAOXEwYzf2V+MM6jsAEQEAAQAH/03McHZdRvB4cI8NiEjA
  38.720 +oW4PoAoZrhih8vtnTo65+1BvVI2TPpk0dxHrmGj4TZ3vJ1M3JeV1MYAMtdhnH0ux
  38.721 +YdvcjV3U0kQq04civNm9ZHKJl06IJXGVeugBJKKyIyk3ivhsN+vB+rwVastESlhc
  38.722 +RrJwl9991pIV72CyolD/czTzL2qn1E99nJbJpmPHW4VKJOaKdKu3mgqhulwZARM8
  38.723 +MFf1NdI3cmYjnx/tq7W2pVyLSZu3vjqvCVnG0R6+0uDBfTK4Dry9yrLtGPlz9Odr
  38.724 +X3XnT2euI7U2WnW0tLGOGR/ZozIysyqRGSHab5QJbeiktC35X8NXr8ruMWLpK14R
  38.725 +/IkEAMRAzTAOnZb8kga9qwPRqUsLSiJ+Ba7OZqYYBnyv9dP54b25PjDaXXAk2Vx8
  38.726 +WcYopEOU2/uijzyX00PLOyB+fzu3+pAbydPyubAXx3Jp3eLMhNxKzek6R5vAFUGG
  38.727 +ObKFgsGZpOgRVEWt6WCwky+X0AFOnZQ65JOLFBcegVUOGmVJBADhc3i9xZfPe8LT
  38.728 ++GFdX0HMUx1eTHW42bXSqAApnbw6kAe9GcS2cvyBK4e5lVMMQGxlApbayt4vk3Mn
  38.729 +MZ7mhZMCde5HxHBgd7/pdYoR3542oO/51gdB12SF4PwGuuKBxeRh55Aefdf40riP
  38.730 +b9/HgIy34nMkhzSXo+Plue98xTzHYwQAv1l55mHHbA9L+o5KszxJShxNocH0pF1r
  38.731 +lZqV68z7CoYfb3f+AW/87dxfrT0AEkvqkJFnEb5JOo5UrZh6ztTFRInCo22xQHjK
  38.732 +E7tOtXSgmDAaxfX2RG2q49Wx+3jRMbgTxiShV72rfT+CRzQuay9KzIPLNlz6VZk1
  38.733 +fmulPpajS+lMR7QxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBr
  38.734 +Z3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBJ5hMe0jF8K3mSp4ImK9mmZxxvLEBQJa
  38.735 +XTZkAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEGK9mmZxxvLE
  38.736 +Z5IH/0apXr6CH5nC4T9Id0vm/PJNbMweoq0RfK7pcGuOvQff3QE8Rhlicjgaw81s
  38.737 +Jm7iqiMQLhiGAGCGFd+4C7o6tO/JRDG50n2xYzUyfgcrHR6IdMKPPKh3SxYidqpr
  38.738 +a7YNW6zyJwZPBqaUyciSOEoy36KBVDEciup39ky6DcSG9Hn+fhIx91BPPZzGIUXj
  38.739 +3JPUH+M/bq1diQ3+nc874jMmvfwhYTZok6rzJakXRNYUjskqanU2oAWJxWWBDo3D
  38.740 +sRVtfy7Sy2GD6iWbfU/+SwDDAdmh+dCLBzZZuQFlqQC3MA4gS3qihLXk1YgzwJq7
  38.741 +LP5afYl3uslJuNvhMztF9iBKLDadA5gEWl02ZAEIAMg3k3sXxi+cc0/ncgsh/2N+
  38.742 +JjAuhn7FGmmRRABZkQh6nbN3qmqfJd/IJmlpTxOGfMnz9/dLjEjRc296HoITtPqa
  38.743 +/m/l7EtmQDueQyl0u7ikXzkhSjxyHHC5lKMok7H35EEluJz+tYz+gvfiRMOK8BDd
  38.744 +R3BS6PvQozFnXmxwqbI0u0i933XnLobeWKeYSnQ+JhsIqJBR8Ri0py9rti/ZsXxJ
  38.745 ++JqXiqDHK+dGgzlwBtE6UBhIM4FyOWM7u54GHCEEPX0W144A6cvrC1xwDrIkdnzZ
  38.746 +uh+RKMugmMjtmt/zMocQbCNa0McCxcEQqdDZVejk71NiGSpdVkv4gHOhae2bojcA
  38.747 +EQEAAQAH/0Ti3kLBRMZ30TLiQlozOc/tBM2aDFtMjJBa0yc9qcldiqnHV+J0XE8Y
  38.748 +6aJmAbeJk6DWaG/01dDuA4YM4bdGeYOp1TYBySGODjaU9q2qRLY8E6kv239dkYx1
  38.749 +RX83hE18qVOC23hkqGlY3g3Uk20l/gAHaj9qv094ktV6J8IupywxHTn2+5eDuNdy
  38.750 +Ur0tJunfcZAGEJ4TPz5R/fHBuQi/JnAQNMG/X+CymjwuoR1AU8MW3VrWsX7uEtnJ
  38.751 +PaDdCli7/oxX2lqrTKs7l1mAbKuXPkpdMbpjsumvp68UfEHFaQyvi5uXhYIUP+x4
  38.752 +ZLCd+ne3hiIyGESZhA1Keb5SE/eHTFkEANLcy30b8K7I2qeSKM2Swo+GKG5dWfVo
  38.753 +T/5UtWZf93ejH8GkIO4AG8LML88nCWs01ZykFQo1MOOgibRn7L7KqpuTQEpAwWPF
  38.754 +6xmIIkr2KTbJt/xEoGY+pE7+NX3m5pnQKvrLCj0lkjFfPSgoq7n+3lmZ1qaxv5CJ
  38.755 +tbxv+zRT0pMfBADzE2rDPCDmSIurDKkfMWrWTtpZs/MO0Y8oXb0e1ZBd1fqJ3Xew
  38.756 +YDkG21R+/xy538SjFfeEw64KKogeUGoEHrKyKW9MDdaTTnKsrlLn2suYPL1dso1K
  38.757 +TD4VBlPqm08JwhnUSZf+VtWSqlA+UJATRmEYWQWhv/ImBpQ5qkoXUIfl6QQAmmfw
  38.758 +/e5DK5aNMrq4wp7PtVnT1qos1jEbsGRaoxpqAGwl1jiT/RI9bfoEln6sFumc6s99
  38.759 +4fqgCwp8mM1yIUhxXp0eqfuD7iKDbo1fIILIIhtqTXm0telOFSsedcZvfxsgwddW
  38.760 +AA2dMS9yzqwN8JLL5CjIgEbzcaHoucGO6Bm1CwM+xIkBPAQYAQgAJhYhBJ5hMe0j
  38.761 +F8K3mSp4ImK9mmZxxvLEBQJaXTZkAhsMBQkB4TOAAAoJEGK9mmZxxvLEdIMH/jlM
  38.762 +Ba0+FoDxCGToSV0iTQL/5rOTSi0gsGWwqGkab44uqPGXx+wlwq61G4W6hT3xwsfj
  38.763 ++HBtCdGQG82l1yBf16OevtQe1QqPczZ7zBcidgNcXq9Czsavwrsc/vHV7g7AC/VH
  38.764 +M2cUXcud6yTCQHXGrzWrMm+lfmhPIfU5ZmrTzRkNO2yCgfDf5szX1jx1r1QciBiz
  38.765 +sjHoZ98LArdsZxXKYQOqHhE+JZ+/RBCIyCK++iypFUddPy9/dOAmnOmCx8OXViBc
  38.766 +chnqUn5XOLzWsVHVa9XIeHSemStz/+T7HeOsMKtA07oUXt0mCmVnlzQnArRKY/7C
  38.767 +e6WXnY168d38yEcuVFKVA5gEWl02cwEIALasLtLlRCbPDtki7xWxh23u2lzd7Py/
  38.768 +Rn3KhT6daFKEcUSmeT4pcAenf5cBCRiJ5RdnzTuJybg/KI9/9WOk9uKkmJEllCB4
  38.769 +rJaoFn9eOSxd5lYmeS4x8Fdk0h55j3FG8tWabd12fUfcsyxHZQdrYR+NpzkRWH7x
  38.770 +y7xAaOMj2FCau+leB/mud5A5aLQdslPT/3mkTNBm6mEV6BPIbH50+nmuwvV/jhfz
  38.771 +co/+d2dnCrFQlaS4G5UOBhEYYSqVHxvqjacyhSbJy4uV2aVCZchJqjuICDbNwjbk
  38.772 +NvtQiKkNPR/E0Kvve6OGuDgKueL4jxjHzkxMAYYZzmLe52yCADZqso0AEQEAAQAH
  38.773 +/RvbI47JzbvkolKEAb/QoSLR+XQ6QWaEx+aXHfzfkGYuR9QyAKt1MojFnEQg28wP
  38.774 +/HfhE9+1kiW/DTEzeu5K3H0mSr+uN9RAeAJyDRriJEd65YzonrJn2iCG7DB1KrsZ
  38.775 +mHPwnJADfspDwleJEZkb4Pp9+uyjE61+s39NtnuWCT631Tt0vpiujoWn84xyA5Fd
  38.776 +iTd0Tfs5rMG1z8Nk3ZFrIuU9H8amdXGAJkm1XjdHdEeFeGvCk52ioIJb23PebQo0
  38.777 +m4fvp4k1/dBlwVD9JtMaJhzbw1mYwIzAA4rsGYwBaVb+KA1YT8lf3ZuABW31QXZZ
  38.778 +doWNk3Ylt9nZsHLGqBOd/p8EANf7YiXXIMvcyRF28VW73jTiytptSUMfOBP1OF0f
  38.779 +C2JhrAor8fvxHLAVf4bHMmpr31gbj6oxop0mw+IvJxzHvExhXQY/Z3P1JwmRaRbr
  38.780 +Yg4LZZJmwbe8zaMmu2xx4ba4zM4trHiMjyIlfRfNPK2pGREBrJ9BC58HYTQ6VY2M
  38.781 +XTXPBADYhNgvttxU40gB+rub8c4L3fmy4flcSX1ffEMTt0GxmPbdmC5b3l17m4Tn
  38.782 +9an/AwxgGS/nkefxC+24w/3g12KiGojEwd5+I1J+Svh5dbHxm6Sc7WVWjkatKoLi
  38.783 +p3QjDt4ca65VqWeLd3noEVpm2EuN2KsQdcFGCu2la3tlMjdE4wP/QwFHkC2LaCDZ
  38.784 +4PsbIYKCiLJzjkMNb01zJq12DNhcfYA05X6qFsuEO4wqv614X83CIiLWmMX95Ti2
  38.785 +aL1+RMisRFBqzmKEXvtR5cqt8OOfyiEYVMko5+YOgv55+GksniksaYQ3mZxFr0Ij
  38.786 +zu5P4nejw4BHCFIggqMhfshmXXXRTHxFZrQxcEVwIFRlc3QgUmVjaXBpZW50IDxw
  38.787 +ZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBIuLowA72bEA
  38.788 +wwwcHVJbUFKMMI7wBQJaXTZ2AhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4B
  38.789 +AheAAAoJEFJbUFKMMI7wX74H/A2cZtaBm4GbRut3V7R8nR4SHL+c6rdU4dFnwZw5
  38.790 +KxArVdHxpnaXlqyzzRcbK5vE3+ZDwMDe4m749RVVbW+ii/lMDrVxi/ApogszwXAL
  38.791 +bI/qI7un5KWCzP/wQtym3HBDKcSfwdmkfM2c8D9dFk3/MHXjl8jCOkScRGcwmyah
  38.792 +OKIClojgdYdgeztWi32d4+HLJcHUOpUEVlybblzFQAv92dmvLqUwfgm4EiUB3DQa
  38.793 +d3uULn7F5oT69Sl75EBDTFckJik2W76fq3xzxpXjYurqfgJlDEhWc+drspf+ta2C
  38.794 +krWnEz16MJH9fJRHqCf9LEgA8u62evv8xTgOnMXvAw56HpidA5gEWl02dQEIAL4r
  38.795 +IAxvAy7EbZakUIbvI/7Ghnek3Cna9Byl64wo1ZQ2rYC9oJsqLcySOhzTtMSaTy1U
  38.796 +8+nZZhzmyh9+f9zk4htx8QPHaCwzGmy+tzJRAonH4WQHCXSMczbqbznxGHZ3LBu9
  38.797 +YEQcs97zpiqFu+F5oz+or1wjIXOSVNTtaWzmLDnLMwf6fzM+uaaYIqeLbInbHU4E
  38.798 ++D8YWIuqo+VL6NsWULPTCOovNIIetgtHESZHUwfjqTPoyan/+aJPsztmCrDW24UO
  38.799 ++/KDHuLnMArkCMQg1DPqapmXGT+NEs3LrHtwzQGtqG5dLl5/Z2TBrOUc3L/sKi+F
  38.800 +JIANjkZtYTnUpCV7wIsAEQEAAQAH/j7t2Gok5kG4oKcj8r3kLt4lZeP7uxtiqDs+
  38.801 +sKat8JdeTKX4mkgeeg9jKDXX3M7eXWsb3Kc62K6htKsdWkSHvUbluqLMfu15b7oi
  38.802 +lk7hPdzINw65wWg+/fVjOLFM1hKFtyPq1AtWEDOsHwWdQaIIdXwgXv83ZN9wwf/A
  38.803 +HI370RDCWcKDNwMHOKDn9+3OKV5o1xR3l1GFFB5ukrKd9BQ3UcyaoYIrGiD80Faj
  38.804 +olAiQQ6CbYjR2G+allE9Jw0m5RhhBDN8bxdvHXaAKvpmkagmrhRXxpOq9wT/bFhz
  38.805 +u+2O1/onAE0CIOC0uN7l9jsIHMBl+o35pQu2WaHJQmoO5sHyuTkEAMvxa2nY28dW
  38.806 +wXfbqPtpe0KE6wfkyo2NAW8TmrZlFV5bYtDsRbQ6u2Bj2WFqG2sRjfmyYuVGxd6s
  38.807 +iQ6w3mdCPxJmy9gNIaLQMrKV/p3EjGA8rJJxePaCsZy3hdWBWKn8kl681LMUJVoc
  38.808 +uau/clr1zTPj4lMJs/P5FUim0f/NaLKNBADutZxGQWTf61RijoZRrEzbELLFkpgL
  38.809 +2nj79J0J+F2iRxrEGXrSBcrLpP9B+zkyDIJgS88Wbrxj77P3A6SFR9OFNsKw1EYf
  38.810 +nU3Daf6MdH9hLE274VImL12Zhmamt6yU2VMd7Eo3GVJHIIAotBS5hgBgsC7IGOcG
  38.811 +rQTxr+dOLKQFdwQA4Ge6Bq4ih0Dm2JbkViDeY5ILMlFsZUubep7kgLM7ubvbdG9T
  38.812 +WtwOIH5Caswu2lwbFxxhvWfYRelU6L2VGtvf90Zuv3AWm1v8cTfllrk1eH8ONfhK
  38.813 +owbW4Xce1DU+eN/HjbLJbfGqNLNoSqaeBXn/4BAgyMAq0bFozZXT3KUL+S1JPIkB
  38.814 +PAQYAQgAJhYhBIuLowA72bEAwwwcHVJbUFKMMI7wBQJaXTZ1AhsMBQkB4TOAAAoJ
  38.815 +EFJbUFKMMI7w05QH/joFvdYvykTSVb9P3hvSSly673Jqt/3GzNCYbKGniUgeGRPV
  38.816 +S4iSMm0xFrA7ScKXdMsRfpk+6ZpZzEzvdoSf46cYDE0dwp2KbS/GzP982jNCIN1v
  38.817 +ytYatBUe2oN4dmmXBdHvlHUVeX1xvdwQqnN/yO8oqBbT2IzJ4Zpd0bdGTiKYUU3F
  38.818 +YUVGPiANdThIwOn2m5dRsyNj0n/WgjHeOLWOft75DjAmFOv0SiQ8XVk3AwRSrCeY
  38.819 +lXofpZjwYc+ty9NMLzkMEQCK+3i5aQ9+1is5w4d/88gM7bd34Ji+NEi3GXM1fVra
  38.820 +RsolCVC4WSUXl3nmlLMV+ZHQwxE/lHdzqJ3ADxmVA5gEWl032AEIALnpeEqmfZZ/
  38.821 +tSYbdNNItDnlzvDiPa7Utu/8/gB0odbncKnBlPOK/eqtEEw4jwjE3PlA3kiZJ4zU
  38.822 +jWxTzvVsGq5/U9qjZoB2e+Zzyv38XDffHIaM+xtj4LvTZgSNqwQl2j4ExbxkVnbu
  38.823 +XbqiHt8alnv6tJ7BZLKxTlud77IVfcm/gCmEaWCXMM7M4NBnFtqTD18gQqKSA+ID
  38.824 +yRz0K0DFe9O771gk61u/NgoD5kfDdVSMDFq7oIauWilf2Ava4VBSs3fJh7ii/R5y
  38.825 +t2zz0GL8CPB9vIFNdDkHHc6cI837Y4ZnJez2vHlddQnNgjP6sqindVf+vH2svviV
  38.826 +1LtYrfDm3zkAEQEAAQAH/0Z8FMZArxazHmvvNvCv/NyCm13KeNZjAWSlh2uGzKEc
  38.827 +qCNEKIPZa4Fg0fAD9X6+nITHqj7eChejsmais7FqpgcIcTNQhhkoUrtBpXF8Dz6D
  38.828 +kV4V71IoINk1QdVyHKd67m5bAtj1Na7rmo+azZeKjgk9OOODsPjqrimgDHN5IHKv
  38.829 +Sar/PPzdfKJ9LguyZrBigXUwaHLXputfMClt4aYrlKEpcgEnLG22GjTuVzPJkmUp
  38.830 +iPKw1DbRqYU4XPRY29kBN0wSTdFZAT8bUJG0pwyY+6Gr/qhkBKJIRSBMgoamj9dK
  38.831 +bg9d3GumdpM0kYu2fXwvGl2v7ggI+ni4Z79C3zFg0h0EANhWIszCoDcddoaRb/HC
  38.832 +uUfYJKX6tSjSpkO7MwOALGUdV2lvVFTTaOyvGlZnbgGnKZZTCsbOxlpYt2Tx/xhW
  38.833 +YWrzcmrFSPA3bwdwdB5VOFvU+ln54NelifzVLK0A8is8V0BQJdeETudJFb7Y0VS0
  38.834 +ijKALrfR8oIDN23dTTPY0QojBADb/1hr7x30/AasagHIspR47ay+68zOVeN8c/rs
  38.835 +d9CaiEvIotrvxL0HifNRUJkkHApGrMTHDYlE/bGgudYDaqrmZeN5BbQNQGXeXDOc
  38.836 +KD4tWmgrzjWnphja8u145Aq1cSjOXFR6FBH7eTPtg2eq48xq7I9UCR1BbDyCoJIH
  38.837 +t6DA8wP/XErIKjgltpGxdqXGOHMUqoGtjXsuuMmrisyNnau22rhy9njYjNrYjqgb
  38.838 +dGERMmirQ8bVrUpqmHBIbuWHD4fLk1paBCVmwROSAFr7v1PziXbcQjq84a3vnX7+
  38.839 +tha0E3cmesjKnGPqFnEDCNOlMU2wXZIhDVCLKCgvwftYNPNqyCpAlrQxcEVwIFRl
  38.840 +c3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQT
  38.841 +AQgAPhYhBJvDAMMpGZEcItz82Gcj6LnSLrdoBQJaXTfaAhsDBQkB4TOABQsJCAcC
  38.842 +BhUICQoLAgQWAgMBAh4BAheAAAoJEGcj6LnSLrdo0IYH/3KLv37+7CqZZl4z65OH
  38.843 +6Umc4qAbBJmvfegY8KezjSH5UsLHskAskVNx9QHp0X3KyyLezIJfMhTFvCYxhIa6
  38.844 +sABO2sXfRSBAhVbydIF+AENxyN6nW4llOx/IuX9OvB05kvhQ43Ngj36HAhnMnpLg
  38.845 +6c4eo9bQhhvoKJZXuivR0wWUQIZzAbZNaEp8+B4GYVEclojvTc07bJwsaIloQh1M
  38.846 +tWRbT+OZkeJOxB+15Sluq/AZA9y5FEZ17Tpz/ls/5o9W4HCUbHoK5/IY+5qMw8O5
  38.847 +ziQR9NKhE4kv58+n35MtGPUf80TodbfsOC6OVHKbeuVoDGBNRedPjQqukt/qevVt
  38.848 +rdSdA5gEWl032gEIAMxAcyz2VwB5IHQ5FrtnN7vTS0iD89LbuZrIcd9Ch6RrbrCs
  38.849 +HgGv9581DmPsNsa7yRkzotXi0S1/dWbk8JdUpMYxeDl+fNQfydnm1qO3O4kdeaCp
  38.850 +qeocacjwNiOYi7vyxLK1Gh9ddOQeJQS6FL/w+wxUkm+uHp9+yVEz1m218sWIlANe
  38.851 +C04nLiN6JQkXOkd4wMhAuAKnSbw/uAqBWNEjEXsGqemyxgHdEuEa+utJ2X3HRwd0
  38.852 +cKo3m2LVtghEmpIji1QRCtBMuP2f7ItY5FMiTkDlURoUJ21GdBI/im3aHoDi+6BV
  38.853 +8IF/l30tu4VmmB5LjqwS2kxS5tUA8DJsjHJ7UZMAEQEAAQAH/2NkHWfMu8t0JdHI
  38.854 +kgJBmQJiMGkqJLT/zRK/5YGh60WcLbH1H2jsyw+DDuya3pDYgmQsF1oDVIzSUDvw
  38.855 +vg611rTHD9zSa0YB7gSF6v6hxGvVlwESbqeIigWItp+dtKmR2huoOvz2SlJTROpG
  38.856 +7p/0UQXQBa4oyagNV0OXeQnMF0X9cAVqogQzwIBO4t7iRc8Q1v+bLvGf8TCG3m9g
  38.857 +Kegi0l/xqtsU6Sa8muiraJsNAtgPdLeGJFRUT2UFMTcYU0XRBW+M9MOusjtxwMb0
  38.858 +n1AbfZ+BFmlsHI7rHs3lAl+t1pNTXcUUX800ZPzFUtE7qvQGxlzoghRkhx+R635Q
  38.859 +o3M2UhkEANT8UUXkqJxoMrX9Yre44dQCc/MbCBsZHGQfmi7sO/8VJRrAtUY7D9zq
  38.860 +04eqI9P/COoB/1AmLvAITeZP0nYXzcl/ajVFYVcRNK9L5H17IPMfeuJUOBYiYyhM
  38.861 +VbxRmhP9lVLvLNTCX1bZ/EAC/pNoLjswxnVIdEH0ZJWljHOEQHddBAD1gJQf7gL7
  38.862 +kEYA42or1bsOMecUEF6YfXUJ1tynUajEfpbDFT6t5YAH3efRecrjTEwgxrmX6SIT
  38.863 +/tRXmuSTzMgOdIFLt1Cj3fQo7Ms/Vdn99xkRd4x39Dgfhrk6wUIurL2wEtga/MQx
  38.864 +gS3PKniNoNH4Zd3PXLYiSawaVGTY8iINrwQAzwMWofBsJnM0WmN5SNusLjIlhni8
  38.865 +JqqdOaDGns6ffw0bSDKybgMEnPZLAHVwkdDrnMwM2eq90c1OtbqwqbrFBXjTVEz7
  38.866 +kTdGNztRsjCRWfG7t/Vzb/0wLyPVNkSb3A0LMo4x3j8HmTNhlbZm4iyOVFapwrCD
  38.867 +5/t31BAkXzWfiI8+kIkBPAQYAQgAJhYhBJvDAMMpGZEcItz82Gcj6LnSLrdoBQJa
  38.868 +XTfaAhsMBQkB4TOAAAoJEGcj6LnSLrdooO0IAJx6L50lzIq1pXcrX3gOX3m3f3xf
  38.869 +yn1Qc/kPf4e/m5ZvOu9PkqKeSOl8WIpAAC/ODmO06twndUp0UXL9Gq7NwXTt2lSc
  38.870 +vwI+ldCmGZKvBAmap+5AIAZBrpfIFnZUohKegVQ1ULwGrNXNje4towjz1LRlYsVo
  38.871 +py1cx+YcRuK2rAQFz7H75RlKkCGY2dFvgqZfTD8pG1DVy7H6SYavUHE0iq6AAB/A
  38.872 +2TWqI8jtYH1iIZ+BFkYRX7NlDZG7aXqRCtPQ84SI9ngL3r5U1CTjTpttouRM1fqd
  38.873 +Ek6t+vg9sMLxV8l3XIZBJv/91z0ZfHfnwRXK7yF9pAnwM6rq4DiBituvJeOVA5gE
  38.874 +Wl08FgEIAJkkTpiMg7snOkmWNyxSYjrgQfGz6fAK5JC8/CAvTUeYZAd53ggiFV9c
  38.875 +Bvkm9YvDRCm1o+Y488GRXEl06qIsSoWavhpDSBhQAe8ZTmEuYubPZxgLQ+wP2AP/
  38.876 +ZLbKb52R/oQ14XctZwn4fSp7p25ZwKNiMbMuILn1tMiBbw7ZtmoxiyUjgYNgBAA/
  38.877 +YN4eMjyBJBj9I+QA9seFHLfBwOIJSCLeGPMr/cUIcZMycUl9yTiXqsb+t4mjll4g
  38.878 +eZo3qBhUf0YMV3qOfQK0oW2twyt5oTEr7iOZT/ygijkWKf+wpmIlBjvaIVnFsXoJ
  38.879 +zsh8cISPigEtPxPi5fMA3Ba0M21zyzsAEQEAAQAH+wREULRLZfg29ZbLSqo/eWEu
  38.880 +kmfLnX8Erq2htlynNL4D7vWOXbNYT8QiakdS4JCOVj3bQ7/MYm5IQIwDZ+4w0bq7
  38.881 +PwS4Ty/uOr+QsvBePH811CeFWNUg8+HYodO9/DIluTOx1KBfcXmDpOkkHNwkQAvN
  38.882 +Vpkpddv4jprvkEqXok9/GtpGyocV6mj+IshGKtxBdv5VxLEas9KW3fLuh3GC4SbA
  38.883 +MQifjGWPAkINV3R0HOux/B36Qv5B871l8SHFa3Cmga5j0EPONa7MgBrGzT3kHMOz
  38.884 +EWqZaU98tVegW2ZfMXkV26iUKAB10xI3Yv0rKGAnGSl+7RW2tNdR3FuXWIcKMJEE
  38.885 +AMJGju9vjrMq2H7o0HFfrXnschQkBl2cCTL2OIPk/275OHFSgGn6DgMXljPMZeQ+
  38.886 +s1IcC/K/uQCJHmnhsoBaoUyV68sFFuJOfRBv0CNatDwKPAXLV5XJFcddBPC5Wyjm
  38.887 +QQD6wBk0rFHE45g/36/rM++wSgT0Fi93VU1WFBo27QHnBADJzB/QV5xkVXctU6nY
  38.888 +E3VG8UXwyMGMXvrbNCZ8od1z/f9pRA75a7o/OlWmYoQ24M9X1PRQoffDoJ5ydbV+
  38.889 +X363v+ZqTd11jO+opWoZaNXYs3Ar92eX3gTllOOn7aVsnwil2+fChUx4qC/bm6iX
  38.890 +wha4y7AdJ2ZKhxFizq/Ir45pjQQAtVTWg+W/QJS9aElls9a6OIXxjPTZwCYLC4E7
  38.891 +TqnEfkcWcAqMHXB0ZZxRhwpzuux/OkPeggiOa5geJuVXhAoQiFn4/BkXSWqcTeAa
  38.892 +tWsPXZzhOBkfoS0pX0gubmr9tgW/k5/ZkzU9dUsOhi0uWh1yoGEjqRbtD7ExIwJt
  38.893 +/PPBtv4/jLQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3Jv
  38.894 +dGhvZmYub3JnPokBVAQTAQgAPhYhBFWeMm2YX2cVy918pjHwlFqWXQ80BQJaXTwY
  38.895 +AhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEDHwlFqWXQ80ENcH
  38.896 +/1I9j73A38P6VyRX5K6J/RImAJQ15CInoF3wwskO1b5Z2aOB9QP0lZFGK8d3KS2I
  38.897 +x5ZHSgC0SfjaaFLOdWSd+cEXF8wyNWkLsUFdMXgnBwpLWiTI0JA3+21cvq/zX80c
  38.898 +vtGdnch6p4DdzZMJzIK4uv3LUk+JFj2V+iwyHcLo//q591VlQMh4hj/2vvXIusLD
  38.899 +AlPKiV5ub84Mw2dg0m4JXIWSovrh3VmShvB5ETgsWVB3fjugFtyKgGZx8UHQY8m8
  38.900 +GTFP51zYF/W23QkPWgnlPYdXoF/cEGkUoOQ0aEf2k2nNGAZmG2lIIfhhLRgSCrHF
  38.901 +oRLNsKelamyU5ep+8qqz6jWdA5gEWl08GAEIAM+hfs/2b3GzJCj3DFOLhGzapO1c
  38.902 +Tf7frjVmaMja553uin+lHnM3eQJTq9w5zKJnplLRYf7Lw9YvdsfVLoIvD/wuXnfh
  38.903 +erCWk7dqdaSqSCD6Fx8hzM611lb0u7O4OH98YmyYAOl3wMfTZ4XSQWd1+169tzS9
  38.904 +5IG1hiPCjKhP7LsRHgYvg9rXajaT+lFfhJcppazkWpDEP6ubF2rsJH+1hRk6A7in
  38.905 +67gbYyZ/9cBB54u2aCXqnktTouikYb54oea57dGg5BXWmo2FEJgjRUZqLx6cogvI
  38.906 +KOOpcVHM0A/Mgdsll5Acbnn09Nbla7rsqEmrV76M7DIEiP8BtAJSCyyav5UAEQEA
  38.907 +AQAH/1bz9R22wNlHAp+9RoY+aYkE0AkvnOJeXqCycLOdKV60pX/rcKMj2iOlUtX5
  38.908 +xr9E1Rzd30JLp4otensZxk5y0yjzalCeNzl49gfcJ8R8I5Tb5478Ir9223qzJ2CO
  38.909 +h+qr9rQvvEIKCswktrgOY6GmgU0d+nm2BNplYPXc5fce8a8tK/X4ej03Jynzp5mx
  38.910 +Cn8UO5wlYFgkohopJ+xHxSSl39GbM2rr5ZSabAofeir50KoflySORQfqogRVznd9
  38.911 +TgGPvLD5TORxZsTWaXKom9gr1tMVLj8OanWks/tk9mEGJIQnnWFux78UYrP7mB27
  38.912 +0SnD7QW676cbKKGTaDcO92ilHskEANEm0TM3xE7+Y4dUagdCeNhhDaR86BJSi9ID
  38.913 +gL4SS2wj8Iyg7qkerFDAlaCMyT6ADfS64hSUz7r1Ch2M3ALHpnuhb41o5ows6T6a
  38.914 +uVBWCLwGGANTUB1qdI3EmlCTr5dGqTGLk3FnbW7owQr6UAZaeY0CbJZM/BIjJgJQ
  38.915 +OLLjvo3bBAD+I3kZ8aeFPj6TNglke0MRYf3Oob1NF0op3+63eom2ikrHt7a36jDH
  38.916 +Bw9lsAxfXA7REFuX0HLWaDJjjyFpRoiFc7klmNzGQXGx7lJVyZmqeSsoZBGA+sWn
  38.917 +Wf/ogvRT5v606vU2eXvsAYWMyLVqm6qvudUIJBjwXpJ1EC7P6+q7TwP+KkFQa5ee
  38.918 +e+zkwofXobtY6l7fRt55TKp7LOWR7BZsV62feh08nsaXKpmrAqrdJ1aBOAptQaHY
  38.919 +w33RnEEG41tCuU8U+rY/LPJaVeXB2IYg6XKalPURzD2xInhqSUkSsXdRjvkhcyQE
  38.920 +flNZ5ctVDPy5Ubnj3Z09pSXiKpl9Fg2oPrJB3YkBPAQYAQgAJhYhBFWeMm2YX2cV
  38.921 +y918pjHwlFqWXQ80BQJaXTwYAhsMBQkB4TOAAAoJEDHwlFqWXQ80CWkH+gMm2ote
  38.922 +VBAHWBeR6jdr3vH3afvpEc9EKxyHm6cB8qh6a7FrhXxPWsekaNNsN5iysO+wPNms
  38.923 +UkTh912RAePDtciUOquY73A7VJRxjoWKTGMF0lA3MUbB1r7RB+By0HOHe51WP9Fr
  38.924 +qZVoWqdAH3senp6N1Ti/yNmq9yxa98LnHPX7Dt6894aab7CtoOB2gZlu3YT3RMLB
  38.925 +0tHBF/ZdfwGXXDX+w+c6prHQTaQ5s6DEdvGxYAKKUMmxFshokwqNa7NDZx9h0IRl
  38.926 +ityqBOPGYFp2u0ko82nccD2R6Mk4iaXqveuoBphNldV32Vira2qJ3/TQXHEBW+gd
  38.927 +R9X28AuHZWwfHIKVA5gEWl09LAEIAOM9HMjcX8JqXEz8exPZqAb3xmlRd2J+RbsA
  38.928 +8yrtgP7yK9zhvE/fjrFAOOvjTyO5C7VlWpmMNFF+z+T3hzx0phBKFuVEbP3e4WGd
  38.929 +nVxfYtMLgGu20tUBg1yrvpAM1Lkt+Zj05XSjq6aSqv3LCya0w0mYSWsBvlnHkReQ
  38.930 +BPiy+lg8rTmgCJmFHb/ioxnUOJcLCygP+zYluCTK+v+OY7mMSRmtUXNXDQr5bMkK
  38.931 +kPsv0NMv1jBrbsmBBoai/ZX6A07Nu5JaO9c8mPA+RQbePTlamh7+05PBEAJi6zTl
  38.932 +7tA4bT1C6RAMdkocwI3tIg7BRXQMHNwkgsGeo9oRb3Ycm52kjycAEQEAAQAH/jV3
  38.933 +0TiP5fZMaXhx5hHXInq1PVnVoeYqeQTV5eGhbbtPRzPbZ6BRpXUee+ZBH4NzzIX7
  38.934 +mbRMcZkFYixpc8gtWE+35yg+D/kyQszhtb+g8BNhfu+ZXoVhLEQXYyjo4/rIjxTG
  38.935 +9uCZjE+O7i32YyLR4KuF6iyEBgKA+ypUqF7OWip9duJR0RyY50rCIMQZHRTkfXMh
  38.936 +vZbQU7Mgoq7aSJHmA/qziPf57xWzl8WbrCLOfp4r4Pa8tVi27pVMDCTAE2QgKiNk
  38.937 +eFLI/39dasOr6CsQ9mZ2c/otyR3bj11QJlN1a4ar5dL3JNqyca14bcI7oy5yFg1l
  38.938 +YFBIgGq1ZmaEu5LP/NEEAOliAEZ8SR2RwflhS0dLfM40C0CT7iHZMYjOMwFP8/ck
  38.939 +9pvuCFTLM3li39sIRYij5E3edyVVkn/htFx8wfhtcgBGF8XU6C3coell1PHxBY+l
  38.940 +kY2wjXCo7oqXkBJ+cVbtuE9urCFbCnRyzI8Jxy3ET6oKKGsE+jcYkSXiPJAeGFvx
  38.941 +BAD5Qq6vFy7WdV+Ql085qPYl6roWBdWhix5eCf7zJc+BO5WWMaWgW41y4qCmhLJ2
  38.942 +IEM86CsFG087VCot1tXG9g0HZa7Dnad+opt3tWlaCqGhp7SRdE8eGQno42aeB5c+
  38.943 +FfpNSIsbox+89F6q5c9LvQeAv7/Z/FxuGNoOmDsVtQ+UlwQAuflDbYaHdjmC3dvC
  38.944 +NhEwiSW3l88Uf6F9Ciqxu0YGM1LaMqXRRVM7yOSSgIiVpioPtpJWCf/a4ITzmUjv
  38.945 +Bx6Nm6Qy+qtOzUqJUdfK6PRA8Klf2W/6EYn8gBA2T2eHhJ+53YnGgvqtNM8sAFJU
  38.946 +URaXGlaY7WHEjpwQzgIbGKce7fpC7LQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAu
  38.947 +dGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBKvftzRxY/2lvaRA
  38.948 ++aKXVQGGzRfMBQJaXT0uAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheA
  38.949 +AAoJEKKXVQGGzRfMrecH/ixP6JLlErczQ1GlbUIwZ+SyH3+Z4pCtj2FiY7iqiKxP
  38.950 +cGRDDaQqcMFbiJBZxWHrL5s6xaaZhx/JqZX4kgGFrtWoWuZhJuOscYvE5ODBvc5Y
  38.951 +NsvuKUSK3TIyfcpx6KGy4dpzkXYvhXh0Gk1u/s1Mfm9iGWt25G1OjcaYyKIeeZJ9
  38.952 +RGzFy5bV5+h1zp8/6HUTSF6+KtoUEdP79VBU9y0N32EJHSrHBurirlAF4lofSrkF
  38.953 +HpCR2lp94Sc0j5xhMsGoViif/YX3rCZc8Xk+rRhUneQ53CkreGYvJbNrgVGAcyGY
  38.954 +/BHjAp9vN8k7XlpxHCNpT3hLp1cENVn///pVHQtJN4mdA5gEWl09LgEIANYjHpX6
  38.955 +nmppT5thflO8ATgt3qP7mBIAoqHE5xdxdhAwRi/TbJv1C5Oz1WUPT5GxeqvIPB6J
  38.956 +NXQJfJx6u87nVxF/sKHXRUUTxiuxGRA8zlu6VbVP7TSlhpGT5Geuxa/Q6GPsC2ik
  38.957 +ytSs5F0cB2kexMUTdVaUCrfItCameqlIk15hcNrZ+99aM2E6M5zSjcLu5Rspzn6f
  38.958 +8JWh9dpIMucUt7N81kCxB2kFKe/ztrc3p0Y+xNvqlsvo9OavV1ig+fPhfUFnLT9G
  38.959 +XLOEWhyah6VSGQO00jPTokWAiFf70oQVZqa/QsSp7fp+rlprvdxeTxfUqFARPQpV
  38.960 +yaT8FZePPWa3VjsAEQEAAQAH/AwrZccXPZ6FiqElesTud9FGBhOirkNDpvpzksCJ
  38.961 +0bBc1fhM1yzL0dMcksGSC68Xe4W8tPH1UUTdbygDb530FsYnUBX6gnTJCWedQnPi
  38.962 +SMX8wncx6iSmTY4DbiUYUSLLSBG5rfJN/zrz8mx6Nc+bEIq0ruPzOOK19MsHhgwN
  38.963 +1FY2L7k3Xv6UOsNRY+YT9Sf+8gnV7wTPaHGaqUWEJ2wrGvrswOFrmgFRFnZpLjFm
  38.964 +R0jypxzeYnxMM/di2wHBlOA4JwyFJMs4RDaDNbTJ/vDXhA68VmgwI9Yz2T6sp1QA
  38.965 +onuPZRF1b6e1/zN6o/21Rqd/HHVfpPBDY/Q688aWR8uE48kEANZ4q7tJUnBUAwvA
  38.966 +kY7NUJ7hkP8/o+0n9s+Nk6R/jxIiI4ZlyorOnBuBNxtvMVtYRKRuxihRh8VLv4oj
  38.967 +s/LTel1SeP0OadZKDgpJuZf4SerocIR7+JJ5MbyaA5qrFx8pDbcp22OIL/Hw6o/p
  38.968 +7U5U0zhX7vB8If5N6rGa/AQW7ryJBAD/meIUmYU2YlUBeX4wAR/NIXBVz4C4reSw
  38.969 +RWPmq86zamUc+tznSLasG8ydTbJ2dd5am7W2BIWqZHorrI0rS1wTEXS/efS5W+1G
  38.970 +gqbxeWGcKrRu8whSRlUWsenr2fVGr+mFOPasdbMPNDZUhGoJMoIlHnI3HecSeLg9
  38.971 ++Vc6JnYzowP/fDHFpQnnX8mo52EVz52EWljZqHpox/Z0T15yq6d2vnuACLd/yOF6
  38.972 +WYg7nDmzCgxpoF1C4t09GzUDNG67BOJP7fPfZYSC1WzHux7eu07iq97zwrJdcYx2
  38.973 +tGd0Aq85SueLxeAczFNaFEIpaIpquEG0CiQVtRfTtZPMT6YQDdBJyapEU4kBPAQY
  38.974 +AQgAJhYhBKvftzRxY/2lvaRA+aKXVQGGzRfMBQJaXT0uAhsMBQkB4TOAAAoJEKKX
  38.975 +VQGGzRfM/fwH/1IP76DFiW1q/dA6Fb0kbpwrfQ6y6nUZ9hFAItPQnddFGeJoRJvh
  38.976 +FFOSVexJSHI86+Mom8EIY9ALnaKInsPcX18iQg8E9oARj3pWDScVu5Sx5aswbjya
  38.977 +z6vMX7UuMU9juNT3qhdZKZaCGWozIyOZTPwuTR8W8UR+3PgOklrGx5UaN0L9iqNW
  38.978 +xqKst1Ku1tQJ1YDfzQwdQ37Z6jqNyhmkjAil/1faBztmpZ+fd7iEpdCLKBlEL1/o
  38.979 +qQ1J0/OUGquFIgi5dbneh1vWUoVo1fqfI6P7YcGzhDYiZs+99a7q7KlkFV2jJFy5
  38.980 +1ep0xIdhRg8wT3Ilo2PE4DZzIoBgBQuCcP6VA5gEWl09QAEIAO2Sz9zvjza/8iW2
  38.981 +RBf+inH2nywR8+hAtwlQ1vBM4+1M6H5mChKSkD8dqrsrkAMfOSSb8VsjIZ5KKUK1
  38.982 +CVoacPwrscudEYwSC8jCKCl2YgfzyM4ue/7LPJMVaCfXuiyfzoA6zMYU0juvVxiI
  38.983 +oiTOlxZjHBL+XGPG67uaAAvHuuwZw7MjtC6S0IkpfvTrCM76ZwBF4IvpiP4H/+6s
  38.984 +gVqmVqLyq1ZwUHyIdB2L7MWj5ToeFKgzoAuahts3sGk44e11X1OP+ivkT2nl77XG
  38.985 +0udeQDzZAtWNyfiRmu9AYcL2zNKYS0hmwj9N4drPJTGMZm2flnyFpeF8YgH5g60s
  38.986 +5utsc0kAEQEAAQAH/i7HeD+IOjptHDiZxZm16Lvc9GWgmVbTm1btwIzrjvvUZ3kw
  38.987 +DW6vxlBvPoWBY+eBd+aCAEnSRpXdA3fbnt5Lk5DL58Pwhxp+GSzsMi1L3qyzL4iN
  38.988 +taOrkB9kGTCzNTkBNI+iRF0Cj4zqDyvJB6hYt35UgJwq0rVg31z+y2CGcQN5BB/X
  38.989 +Wk8mfxVH7ktoLhz6dbZDoohJo6TkMsJvqpIbZLofsLjAeVGMO8bb9dAJQDa66ZZV
  38.990 +RVD/WcUoIJ+xI453fYQKdDhNaC+7xo1vHL/6KTSHV7ghqLNCrAmFKhVbDvhA+VXW
  38.991 +nrQylwVuWkHnekgVmuddrjhPIP5f9kPWI8PmAAkEAPFi9jdU83Z6KM1VwguERfIa
  38.992 +HoInz2qIr4sgX2Y6g+bkVDGGLVovxC3g0VlfPNiBwf3FGTd1Sm9Bn+6DLw4EFW9P
  38.993 +k5BX1hweCJp3UqtH18r5FaAUaGsey6H0Cg+YsvfS6jd1unqrOOKcAtBs3du2NxwN
  38.994 +MmSfky1F8zYd5I6P/j4dBAD79MEouhBiYpSBbay0JVQejK1mB7uSfY/Fi0UZ5mqc
  38.995 +T3fYJQF8Od6zvcpX9x6qZzg50SmXcv9x+2Bkz+nsXCMLh8LCRWrdNNVXrgyi4AfH
  38.996 +VLbBAWnqDkmDQjBO14H88kVFc5cSZ/xz+1nw9UAmPtWyY316fYwPdW6Mkb6RZAjy
  38.997 +HQP/UzlvaYUvIuwJExJTPFXUMqO3/ACkld3jvjv9Bzu5sg7ZV2DKSECMGeNm4YC4
  38.998 +O707IFx+YwMaf3J7X9826k0a/nYoZbrWy8poqgWzqdyZG9yFlm5xhnQpOMUy/wg9
  38.999 +WmT7wEGPl0OplbR8C1On+datSIW+KMVSzbyR/b1cEVCrVOo6F7QxcEVwIFRlc3Qg
 38.1000 +UmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgA
 38.1001 +PhYhBCpeTdqGcjSFIILmeLxsGX3TyqCGBQJaXT1DAhsDBQkB4TOABQsJCAcCBhUI
 38.1002 +CQoLAgQWAgMBAh4BAheAAAoJELxsGX3TyqCG1hIH/j3BEDqCQZl0eBpIgl7tMnFT
 38.1003 +V+hKDMaZqGSrLJ2Eir6qClTDcTNeWKhqmZ6eOTHvYWcRb6d9qzPXq3CRK6KLaKd/
 38.1004 +uSWdGe/2QE3A4szgFM3b/fGibhvlBBuErhpbOb/QROs6ffG7CC+zPXFzA6ag0HFv
 38.1005 +s4+MCKeB8X3HQ2yIFloM6Gfun+hEedCfgNiLV/1Gi9UlHe0fR+J4nV/LZjyRrEBQ
 38.1006 +uCJc8QnKtmxqbPcVRFxaJUEtkAWkb8sDymOjJ3ghsDELVmxZLwBWeD5P616m2FON
 38.1007 +TCPGvPwZympSj3y/C0WH/GmXETjk07pvM3OfPd+6S/E0d0uFFmd3VDcE5e6eP2Kd
 38.1008 +A5gEWl09QgEIANK3/H034YHxnHCT/2yDtlXZriJzmDIWhGgrbOhTkMZl+6Xgutpt
 38.1009 +5nIRd6otnpPTcgChcvHKFgIQJ1s8Nyg0wVztFgig/1vMwiPXrb28wUapuKtKl213
 38.1010 +J0Rd9oHrs8GKLSj+iPC7QPVMguOETWmbbiBwRbYqgP+BhlL7FYyyB3wEv4Ra1UBl
 38.1011 +9iEo0fb4j4irHw2dtT3L650EMFavr2EfH1AlTQCDlK0dqYAW7A7LMd6I28Av2nf3
 38.1012 +macOBSOEHO7RZirqw9jt+2zU/mfADGWFBm3+uAINeMnFZmqups6eYBqfk3/QSQSS
 38.1013 +qs1xf4EqnYt9/MfucxGPPvdhZXlnmESfjiEAEQEAAQAH/RDvgx5ARcJXHBrrNinv
 38.1014 +SxIK0QVJU5fg+erSZKomfzoG28sY7QOdthoAX+UATiC065Jz52RZ+NtZF4SsagVz
 38.1015 ++f+BOZZfdC6ZXhgZ30ei2kjW3rX7pICChVgoEiYefr/FHnyPOovYjO+6IsHs8fjV
 38.1016 +Kmx2gY/SyjPe4eAc+H4ql9HmfXD33qVEAQzWxvcsU+PqMQJ92Hx/kdbn0cF7ycsk
 38.1017 +rOFWiXw0fbWQAu5MgKwyq6JYsU/fIvQ1vhpmvTaDaiNc2iemvpxnh26BQQH7R437
 38.1018 +rjLrOCnXNguNqOeiWZj6lQ8sCWNt5v4qdYmRWD5WcPKQnlSGnlTb6UDPx9+TKuZq
 38.1019 +LL0EAOE6Q9u6MmWgFDY/wdPQyLTdzEHo3v3+bUbGteQli5U7OjRKdKtfDCnfal3s
 38.1020 +5XYfiXYCOd7KOnprFgewg6SXsVhk6RuEp50o5IZ5IEkPHKHUgWC6fRj6F4BUJ89G
 38.1021 +NwB/rv7FUFkM6t0Y1WLol1yTkI0VoBX7d2oHel4bYnhYymVNBADvgj8jjv27/Iz4
 38.1022 +D/J7BFgJKvokz2/SZCyQGGZoBttJiY420hQdrvI2ELSTcdG3qaU4cRABhLV9B48T
 38.1023 +nJlgnwIjZroKpOxmvqzZnHK0/8+/tjSROP1JBB+OnTDqAo6FS8lR0SuzjTHWChtZ
 38.1024 +bMmspXh67cLh2CZh+Ev9qn5dN32SJQQAt1rpL7SY5nkzjmJz5UakWqER35k91HP5
 38.1025 +G3L675SkQSpOY3vQtWWcmfSXPa6v+uJh8d500euj23PCVFmBam2UYJMAwe8CyLGg
 38.1026 +GKZ4KO2VJV9zHEzlZvi2EsI3F2Lio3iDjD4ubw2MMBN0IuWitYo244EqC1TCk5ej
 38.1027 +n4gVX6Me2wdED4kBPAQYAQgAJhYhBCpeTdqGcjSFIILmeLxsGX3TyqCGBQJaXT1C
 38.1028 +AhsMBQkB4TOAAAoJELxsGX3TyqCGe74H/iiYWaEc9/FO9E86Zo4vqEqpNS6emb8C
 38.1029 +zBc4jtx2CycXsVEPF1NVIMcitVFiwET/P0Z6+N7gHTk/g55uwpzAOYSGL5K27VcO
 38.1030 +8xRUGzO81ckSfhLxqbx9O6ZCC4sSN8xsNwg9XiJB/eEGIw/+rRxN6JgLkpIKp7kq
 38.1031 +wf08PWf751KGt3YK7GSvRj3s+wPwXBxmWXq5LXwVoX+OJqa68YGj3aVpfeYWUEYw
 38.1032 +TLCmyUlxIGU6tV5YtpgwBbQjHBp3g9aIP9N+tCkFLo7C0CFbwQeljv3bIfRyadrt
 38.1033 +4g2b2jUFKOh1muON9Ll3qBFa0DLEZKCLp6Q+R1e3EHDh9hvt17USpOSVA5gEWl09
 38.1034 +YQEIALUUb33D5Ix+7rCNooPt6WHrSOPiwh9jtXauuEaKN85wsbRYDVVzYc6jqh88
 38.1035 +o6DqrC6EIdaCbyS3vsC7EBcCChsD+9yO+U6U09+zKhVRidoUWs0YjyqH5vmGJhpA
 38.1036 +gtG6uCZALnN8T0EIf6eJEgPQ0EXKI2RNH5X59doU7muOCozFfEQu2YrBpN23ykx/
 38.1037 +xXouhWkMDuMi0nzueXXGclVEzUQs6NGK0rTvBLgO7PNl1o14sswADOTcyWgl5kZv
 38.1038 +/Ci9kJMhKfTarqbCwqSHV7T+unRrvoxoilHDFflQgFKmdS3hQKUvU0QUts05P8Xw
 38.1039 +O8mciVYYbzQJA9tT23zwAaa8RCkAEQEAAQAH/AoAx1PsPAuNgNlcnvX+G4le5QI/
 38.1040 +EY2IWuA5MKbSQIOf8sEiqBc+A3uAdl0OuCn4ghXOaMwfx8yrIIInE0bMxGAlAoch
 38.1041 +mCDA1J95Qew25Trt1ZeaMWEebCJWncjkzWqROlZVRKZOigDusOvsBNm/HEeZWLEp
 38.1042 +bYLscaoKw/efEMghPNgVppaleUUIA+tE51jSznyamNDDoyuvjyJgeCz4VS3VgXFy
 38.1043 +urI81rTGUVMZFjWlQa4F277l9tC0ahribIIK1Snm5i2iLIt4eXX8cCMcRULnPcYf
 38.1044 +vmoroLEAvbwCH3IY0U0xLGbdHeLWUaKRKM5M6qYfDtPAK0a5pN0P79lecW0EAMg7
 38.1045 +/YLmQ5op2CQwaLDaljLGzfruWNJplsKieomQABJuiklGx+FDzWsLdLHKggWMZs1m
 38.1046 +xFY+M5tHyIoRHMN4pn2e6Eu6r/6g9W8zXbNHXWqFbQq8KvDIobQnUDsxkaTBbRPR
 38.1047 +1xbwHs2B6gpeIl48ujqS/PaNYo+r+mXrpcuKxRNvBADngsuhh2DYA4Wi6Fd6m+g6
 38.1048 +igeTotNi0DuVaCYuS9gVHyCEgoXuqbW+zTjyxMe43P9ew55xgx0Gt113yc5Ng8zu
 38.1049 +FbYj1zFMXiqxnv2ysmFWx8LzQ16tpb34oJ0aiAYrFYfOBicepmW5Zutsr8GPDSaw
 38.1050 +gbI1cPTrGyGsV76h+Fp15wQAvdK6L1IUX0QzvNpixyQNwW2ITGyagiAW+0aWl0ds
 38.1051 +NT9Y8u7dAlZ+5FZgigoLm6g5VsDodAnrtqbZ/dA/NbAKqGG13F1X3kWLZjyS70pK
 38.1052 +xaccuBD/pJSy5xINxcH5eHDZTJ9UEa1SPuAmc4AWSUC+ZPa3ExzffB1JCGmf5hzH
 38.1053 +4iFBxLQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhv
 38.1054 +ZmYub3JnPokBVAQTAQgAPhYhBHQIXut3pl8GiQI2n6Iyjf2MyU9ABQJaXT1jAhsD
 38.1055 +BQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEKIyjf2MyU9Au+0H/RNG
 38.1056 +PMwHcL/Ao0ZuDjM7dRl0KvAC0gRgwCrjuwuEX9pajTqB3gWmT88jZx1cFdCO3v49
 38.1057 +vKfPUAS34OMq+Y0A66l25vGxhPrGIgJf8J604FTT2BfFxs81mUNGvaRUUbE1IM+6
 38.1058 +6oB1fDR5oYYrvwFclC95MMuks5C0TRyT6jOqjoNFYR3Yj54BbMAXlZHwl997yL1N
 38.1059 +eodcfN4CAbRD9m4dQPJx++HEM3cV9rRVibXjHSsG6wzU1YOi4/OCgVlSXm0Rcxnh
 38.1060 +76ZIgDZFeDwb+qI4gAvmZ4034P5YHHD2Hw+Qahvtztmm07nJk4PFKxA4otvmslya
 38.1061 +ViDVAt9PKXrufiG9rvSdA5gEWl09YwEIALGtSiV+kfbq5UyF/Vs0GiSOKGCaVs4P
 38.1062 +fOi1PLLOZ2vU9jeUabq6vemvI0tb1CepKWv0DLtHvhnmAhGd1SP8RIm64rhqMHXJ
 38.1063 +4rDlsnVNCKW2SvDSFjija0w8eDVYpu6tWPDfx3YDVjwg3Eo/5Vor+BeElLubeMl1
 38.1064 +xZD9aAeo5K1Yb1hBVW7Tea7nEnncuzbgo0/8N2qpaP0vPUgaOwxgSDHWAjBz9F2g
 38.1065 +wjKPy+EhxMdwUkG2QZWXUBD+mVFrqWgj3fKbbkR/+V56AhJmT9/fLhcEjnGSOAN+
 38.1066 +Ak/iTYeGTOFVviZCAEeNG8OWm0+qjWeOPNtg2XhtiEAvPIEFeYCV31EAEQEAAQAH
 38.1067 ++wf7J3ehspGrjzatw0VDqXPSoKBC0x+rUG7tSum0sBxQCeotgcZSgoiGRnaXHqyv
 38.1068 +sCbH9zneZGqqQigabHRuW4HKmNxGYNe+O2Yo0hYQPMgzq+uIhqImGstU4S1zIdta
 38.1069 +gub5TTf1uPvJmhcKBkyvDcsmXQdo7AA0GxsVMmCpIjth7RGH1BqCJ6MmYTPNYvip
 38.1070 +qD0rzmRWekGEjX0b5GO9iaeKeeQgs9+6nqVhGrtcSVJ6kOd/awo/2mGwlRTeGJ/5
 38.1071 +PAIOpViwvzNh8t/SNi2SX7SCAf47lJiX0QVrjTJ7dDg0N77urSQf46bJqeW6xlgW
 38.1072 +mvyXukM9GfUmthy9yqp/qIUEAMWnHXVQg+a36fRWQBpiEHC23kh2bn1TRpSXcgAZ
 38.1073 +bQb6zVQ9xvmBHF2NSmnzjCcKdVkqDLDKZhItVOW0J6dxfw9FduAXQ/fD9OEW+lUy
 38.1074 +6mcahGr10FdGzGKB0wrqVt8J+J3/Fjw1zKoYDuuQ9pGI6ZnTvACemR9BbL+9GBDr
 38.1075 +cIi3BADmIJIWJ2HJMHsRgGW9CiCuoaj1ozGwOGEsbYC07L67v40Ijueqda/HXvdh
 38.1076 +qf1QOhbd1LY6PztsZBULIdpYRaqC1WkulwuKlJGg+8ZLUckmC3ILb76AVQzquDt7
 38.1077 +Yk5QSrwtlOQg8sQnMpcE25PjkeLR1bQgojrrdsgqpb94YluANwP9FO82uZgeiNca
 38.1078 +hV2VSe9MMkbTxaNCIM3cVZYyWbU10KZRX5ltJa7nw560xutOiHpjxdPDmN5lp/c4
 38.1079 +59LZkxlFno0/U0IUw99eAM0UhuU5VdnRf4RLqKXOgUxwjZC/Rbyb5Lnadh43mbwE
 38.1080 +vRERDQDW81POiiuojXvN1oZS7wJESY09xokBPAQYAQgAJhYhBHQIXut3pl8GiQI2
 38.1081 +n6Iyjf2MyU9ABQJaXT1jAhsMBQkB4TOAAAoJEKIyjf2MyU9AjaMH/3FTivnCuy89
 38.1082 +fr1oAAmm3ay3S5+i+aiEqevByqs5w2porvUFM5kc3U0m2CsxFgawqhhjJ0soryFG
 38.1083 +bfjpMzCiqwTj0iv+MS8x+Os8JKCLRitqLDc/ACqUMK+Dh9uSEbhwRqQMuY+3eHVE
 38.1084 +vtsGdfffYZ1KV76E7VcZxmwxhXwMnnJgqMGvs/QSIgEX2Ak5B83IoiLNDQ3eluu3
 38.1085 +u8wYFbXYeC+9L43zMKTua21Nnc43JsykP5LZQZNThJr4KnPN/lpZohdJMPdesVYI
 38.1086 +YgKmSVNKwzxXzgwdAB77v1FT56XGov15TqmGFJvzqs4l/udPwvkmzEZD6qSI3moT
 38.1087 +u7PFBLx63DmVA5gEWl091AEIALBdf7x7dCG1daje6hp+vPBD63LJHNGRJgxrHTtc
 38.1088 +Jvp1tLYI8TThRIxDTzKSwAORSqGs6Au14KqXrPFtVjEbpmieYLADSMAbTYp8j/JI
 38.1089 +Rkg9BsqqJenPDUlhveq16uNaOgSN5Jk5s3YR49TVeqPOcDgZ2nshLCNuY7AEtGpD
 38.1090 +RUgBpRwDWFyt6etLkhjW4iOj6Fpa5SlERHNn+MU4iq+8wUWAKefA44NWN8V6hJcv
 38.1091 +q1EFq7xddL67e91tqy1dKsux+LxjOSHlwEYpHQc5tspUx6TL6mqnjO13fBIgA7Mq
 38.1092 +KQ8njLv9y2JuQB4ZWrOEqwyq1ay0/GDmvhTCzDsY0CgdjCUAEQEAAQAH/iJJ00tM
 38.1093 +PyxMkLcHu8Dx8f7OXai/4+v0ic6xRoojZOqd1sfrXiXXRBH3Bh9Be7ZV2YosSSL5
 38.1094 +tdfEzFlV1gOPKh+95vNheBPtWvp5NC05Evz5bGgbg2p9GEqzh45p1uRjxtLa2V5W
 38.1095 +4wap/L8E0CanvJaTpC/7J48t55CxoXflY0NXx8lKZ8N0TO8gd4lTSSN9Ad9tycxA
 38.1096 +68JA4aabkNV8mHjV5ccbG4wslFaiXMb4M3O/x5GHzKG7zPLXsSSQpxxP8KAuivX5
 38.1097 +Pa9uLRTrz3hFKp7S9h/C8ISW1YxZxH2wtfycVN6xSjXb8H1GK0Jby+DhhNmhY/7e
 38.1098 +lXDs0mzZBd85BbMEAMlPWYJ9qb4YAddq/+xkIH+c8OxOGqL9wc+v8HoTvyfXe0ZB
 38.1099 +LjV+CeW/qLPgmGU0XgMjP4GzU4LDVEX7XHjPperAfMyimFCD4cUVbiQXu6g3OfVE
 38.1100 +Vx3sjN1jVgci3byf4uLoxi5y2FtV4eIU0V1UY/Zi2h+ufiEM3NCXpcwA1/qHBADg
 38.1101 +R0zRuZqhjgsj0E+P1jv3JFnndKt5UAY4r0VdG6AXwi0kFciVQww8vb8FauAUA5Ne
 38.1102 +l/wFZdStHJ4utg9y/MJjogvKr/sd/eTX1kqqg8/Dwl21ua+7y0ESfQPk93dLxNfL
 38.1103 +1HrVChBEF+rzZohXrote44CY13JC44G84NSywajS8wP7BfW8NXLlR0I+1ttCDohp
 38.1104 +VOrqD9VA8hcuMCi0O/eu0N8hmaykKUHlnzCO2gdzMQh69/4HUCZEVy1P5HUge6pr
 38.1105 +qL4pl/jtD1Yz72aCmFzdRpXm7GDoi3fQv8C7R3PQ19bNcYI2/cz5OQIDvDMyXvCC
 38.1106 +dysGemdGUMVqKstdT+n2WyRXT7QxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVz
 38.1107 +dC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBKvqYkJ6kXQeKoCft1k7
 38.1108 +e0NrbITrBQJaXT3XAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ
 38.1109 +EFk7e0NrbITr3D8H/RVYdg5oO4OnuvgTTFrDbvFI9HnO+WCWEXsnARJCVjVhcTrX
 38.1110 +0/xW8h7SQJpJlXmxOnIa/Q1InA/Xu36IyaHntgT39UPY9XCV28O7NnGmWMh2w3jN
 38.1111 +Rr++wUgwCtlZn1oZ/aZlHfFTx0rxN0l2CB8VKeILCwDh+GopDu0+nP8zOnbvedyU
 38.1112 +2MUtfX5rrNmGwpqctWFzos0tOdFX/IVKltm28aGGsIl/K6Br2A3Xi4fRFpiRXunv
 38.1113 +vUhzPLsbRgssB6g73Ds0b9xA9imsHPsqV6YJvFa5yyyeMFcIVeTR+a3BYgDpwN4C
 38.1114 +bO/PVg428s9wgUKBjWiTcqmIt0LAwP38iLR0fsadA5gEWl091gEIAPcFCRq6O8wk
 38.1115 +yQ/ZRxFSxmZDaJcIXPJ2xA/i4ptJw/P+z0sSqB/R5HrOgnsLR1UxC9LYFXL+wBFI
 38.1116 +xOfwHUixbiZUMlpMvkEUPZkMCJSAfTpWbxkqjzgoCzAnzmJn6kNddVFUFE+OZ+sL
 38.1117 +Gii8CBgxtTs3kNuIuFTZHd6vEhKC3A34LZJyvZ2GGvJBRJY2lyOuooJVsvXs39rJ
 38.1118 +NtlmwHn2ldRGET/FgSYwGynMsqGjuSveT6mGjukr29O4wsGDL9QgyCQfc3sZKqGd
 38.1119 +7DlU3xcSWuIOF0Vx9jEfWeSXvZlJIKARe4Sjlhqpcq/9ukoWQ6siyJXMGZ8W7QJG
 38.1120 +BGEFC7aHyBsAEQEAAQAH/2GnvvqvB3bkUAyQ9HSXydGh8pZK+xvr8gTpyHZlyi8K
 38.1121 +3H6saITz4KTgQVtNkSzP0AHR5WDp75qlrxqWpa0YYBiNDr7+OfTWgKehxz6WMWu/
 38.1122 +wfosBiTIR+wIwKHMvSNWrkuxtrng7ZpRcE0MURLni+NWS1FPEriQgSuJANcKnt5y
 38.1123 +KRIHbKw/hyswWUq2FsV5CB8Hu826VHwn6LPcKPWou0Mjqbcj0yzRPGAk9rJ3YwKF
 38.1124 +pwoW+agDgCdm9oPWEPlZyJAfsfT7/xxU4tekcHWF1ac8aKtDeEDwN9gNkaDwinUr
 38.1125 +o3bKWzmkIFWvaVD9VhNUSifmJDLXWmmZFz6Vfy8FTmEEAPi/9ShZTufC80Drk0S/
 38.1126 +b35mY6MnDY3cBoLzlKbIv6DcUrVOZhDOiG8bnSMVAGZYQPUK4eIW+pGl5nFAgjip
 38.1127 +2WOyI1/d9+Zh2S57aKy4BbTtBGr8igGb+re8f9CGK+3/VDU4i3IRmifOPNPznEgY
 38.1128 +JKugpUBQILvn22GeFPEM4gGLBAD+OCsXfOjIRKRbed9udQu8T7jYE4CrrYRqfHQy
 38.1129 +FGaLFn4isiF5P5xvj9FUaK5gGOvmeWSKrugpKJVnijoEy+P+Nc712y5yUdmtPucq
 38.1130 +nYM0msvhOqCFvw/5lqyxjtbGGcmM0lsDcFl3qcgaUP8BpO60SgOzvfdf/2XLuGhY
 38.1131 +WlcFsQQA25Os+ZY+nQIzJDtD/NrMfkYLg7D0Mz+AF+klSL7FePtg0CIqfcQqCvcT
 38.1132 +Lfpn4RP1ESjOKnFLz9bHL8UbH9E7+IRmsfWiTswnAlNErGBc+qwCgiA7IhpsQQHl
 38.1133 +Vz20CyUG6InShUQXT+Tokrs9K7lG6vS7PwRoiR66+EigDPccCrFBNokBPAQYAQgA
 38.1134 +JhYhBKvqYkJ6kXQeKoCft1k7e0NrbITrBQJaXT3WAhsMBQkB4TOAAAoJEFk7e0Nr
 38.1135 +bITr7BAH/1yGx7ByDOGaYD03ZoBThXw3jcdb7W+YOo3Ms6p9wTMGfbCsAEqnrEze
 38.1136 +6whU41vodpUlhdVGhxD5FCiI0KRBvkvH1RtD9Ka6NC1ecSih4WAVlUz7trW8c+lf
 38.1137 +khJqoJIkFc2fZJGopH5ytPISopm1tZU55rVzYkKtXBdLg//ce+MtuqXpbVRbkCxB
 38.1138 +vzIugVFsPOiE6RUUhU29zxNOEIJ+ZsUxKcACtSvDrgFvG5gQvC/7HEvjaIYKa6l0
 38.1139 +XCuxh8vBg/NkBQJuLMrCXG68AUHvU8tA3cXCV4mg9BdQ4f4aMi+VNKHPGgfKhZcP
 38.1140 +r0C/ItdT1OQA/ROJk67v8SepMcVrjmmVA5gEWl095AEIAM5aBmfgRPQfzZtqNFkX
 38.1141 +rtRIFIL3dYy0ewrfVKkJt7t7GRJ0pvOYQxtMbywgm+sNtEMfwVp+QwOcAUcB18qW
 38.1142 +FzVn5L9KjsptG5ad8ubkNqzw1bihGi4Osi6TxciJLj75UXP2q9lRPMsTpwx/iMkU
 38.1143 +leWopt4M7VgcqPNtRIppQUwYbUhlOMYNEAG71p6Qsa4y5SfDwbH/lyIKdnv3CUsO
 38.1144 +1n45Fpig3psF1hd1lCT4AYGfzQzzUwnypg3+BzUCpeOxMeAU2FABeb6Oij7Ciqjn
 38.1145 +HJh7dFXunGffic7zvks824a/V+a0+zLlq9i1Gfaj9r3zwPYmP3Ksd9GJZ6gaOceI
 38.1146 +5OEAEQEAAQAH+wTcihoYZod52FY5AlK3BB9sM0+ClPpjpiJzcIMq/3EjTUvqA6Tp
 38.1147 +iWszOctIWWQIRp7uOJfxMZL8MeuCV5smPhW8BN+c2hBa0bOStQ5Lgh5A7kgTQ5Ki
 38.1148 +NgBy6s32rWg+Z3Tb8uCD0XLXW7AnsQlLutxWRNgmZdEVm8VgZaT9JdStE9F92gHn
 38.1149 +SvM3lPy0Y0bP9j4YwYkVudEX+TzX0IXlUhpY7ioWXGnZgNInLPD7siGJLB9Mw3eC
 38.1150 +OrK4F8NgPfoUgvEpmokyvyZfPuiphUDZfExQaQ5aEIkADuGLxOkEr3p8Kuu60TTq
 38.1151 +6IDYI2I24h+Noo5hLaae3uwwPO60gHB7XKEEAOPQ7+1cfKJcOjMemuU+RBWoh2Df
 38.1152 +PPUgtFQQ+U/VXVEXSgUw55VWSrLak6nNizd7pANPK+aglVk6VvjCYDqo2meOGf4V
 38.1153 +0NQtQH92AWglzseFbHmoJyoeT4J6l53UeT0ZA5uu9mQ9hN3+6fcIZKPOSr0ellhX
 38.1154 +cIms9fKXbVXlFO2DBADn4UuYYrdqk9fSilf1Bpu77CsyF9takvJEGzstPQPCeQA6
 38.1155 +BiT5pefLFmqv89ZjBW+TR5SPhEZijjc5pQmn3EASVTSaGCdN1ouCLX3VL71ILM5r
 38.1156 +oVLn1L0lkkMuQsTc6Hx/OB6Zp8NjHVW1xhQov/Lx7tGORO4UGhqRGGVns2XaywQA
 38.1157 +wP5+XunKALi1sPBRuBTsyEbyFuqL1z+4srZg1ZePEVs6ixE1/S7j344TBBIuVzWl
 38.1158 +4mN8aKcVYas2Ebph42WfEJh67F5gjELYk6SFzzkMZDROMvb7STWUpdpj9MIDpTnf
 38.1159 +NB5j9HluaZIn+K+gPKLfO35OGo+Efd8ACMeJjyvFuqc78rQxcEVwIFRlc3QgUmVj
 38.1160 +aXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYh
 38.1161 +BAllN3DxhBSxviFclZuTV/46XYOBBQJaXT3nAhsDBQkB4TOABQsJCAcCBhUICQoL
 38.1162 +AgQWAgMBAh4BAheAAAoJEJuTV/46XYOBtyMH/1a469CQgelc27UYm1m2uq8RRpbP
 38.1163 +Mt4vGADavGHQoOXUU372xrPJ3MvsG3eFWVF1UVMR553FC7trljSzJWB5ZTakj74O
 38.1164 +cpXLSeyxnSezqjiOJF3JGc8VLBKQdVlsjWHOceH3nz+7ivUVGj0QwdV3DiVyTQyo
 38.1165 +iggkzWe78G94QlWyMWRgUGlL5iLE4KYGTaD5bmqn+/HcDqlxEm102gIAKZANgpyo
 38.1166 +C7WYNvAwTMp7NC1mUvOWzQaNOdlk7WvseU4COpDXWn9YNmejkJaMcBf3w+WNnuDF
 38.1167 +JPND8OwFDypwSMcQkMjqDgrUnvtU+SXn9jNK4abqN5XttNOmKi400euXf4edA5gE
 38.1168 +Wl095gEIAPQ8s7EW5Pf92vbLt7n/JMTQwg9vnNTKfkjhZeTPHd2J9qLU6UYJvovo
 38.1169 +zNXT0Ynop4NUGS8QU08kqHF9LKK4/HifqyVbocxn0yym5S7pNe3jvVTPFXBeTrcB
 38.1170 +kpFOsWsFnvzmt/cFk1PnFWMDxu0cD//qG+UeS1ktQnGZK/TnUhx4eSFcWU3qdavQ
 38.1171 +U6/JCrW3zQ6YOkYFYZl2WhC6vX4yQ4VQPoxPNjm41e3YFUcmJI8Z/j7EOsoIbVTo
 38.1172 +PqfC5wqfbq/Sk7Ibe3wUMNvGFQpvbLYrI5yE3j9+nV74IfT2uBlBAuhbW98I7XJ4
 38.1173 +BvCnkcg/qeT+btD37u8mSQw9a05k0zkAEQEAAQAH/Antys9M8zd6sDNewkQTMYM3
 38.1174 +yl/WxX0oEzyyvxHvcpMeR/LELYyNmlu1NdiOgSL2XJL78P8nDn/16Uwdztn5o7fi
 38.1175 +o9JDuJ7m7KCQ01nWHL1kR/7h4Uj9aH1LmNID7TYA1z8IQRvPc/cR+p5ZGbXrcWIR
 38.1176 +uhsVIXKJYr1cAPu2iLHEBrCJaYP2riK66rrEPskr8yQP7TaXHfX7QEw6B2M4Exp2
 38.1177 +VwOXuc+a+Sfo2yYBqodEG84zXZbXmwJ9oo9u5RdFsq0h4m8PqSTa6jM5oHDGJ3JD
 38.1178 +acuMJA3GJ2iT5TVeTrj5AvFcmB/g2PO5H4ZVXVVVzGKvgHoKcqDZO9iidLWcoSUE
 38.1179 +APRDfyKsn1OT4FYpopXq/TRCnJH9ySQAV2rljrH2PPDQqU7P5sTY9E4J6GSccZJz
 38.1180 +a8jM3vqmWInXPpi12ehQEIMlV5FEyUSY/nR/0rGMLm4gHFWwy+DvfdxbxZpH3OSC
 38.1181 +3jNYey1lj5G7d/pop3QYOyhFQFrTtFRAkLVGioJKUTllBAD/+OD60+meiO5J5Udi
 38.1182 +kT8F2r/8HdRE/MRMHGpSkEwnoY9r4w9a+15XVGGMNwjJpylo2IYrJf+bapNTvGTZ
 38.1183 +VbYOdfvtjq2lQ/uqtri8T6qlIxRAb7RRziUzkvZmZ5q39aJCqZl2eGt3SPknp++e
 38.1184 ++kGYteCbFWnIV8hpoG+j5ha/RQP8CT0I96/D0Ee8r4ObBgp3h8saAcOx8CRTy+Jz
 38.1185 +fnx+K1hJg4I/Pv6Ko4WRZe4UlEJ4eiU7z26qxUYJmaZ9Xhm2f2yTd94FWDezdsnZ
 38.1186 +1WqQqK0FweW7/SRj6Rhvtynz+chmdEjyf+Uqf7J4VNb3JsQS27/jriwjRPPBOK3y
 38.1187 +y8864xZQjYkBPAQYAQgAJhYhBAllN3DxhBSxviFclZuTV/46XYOBBQJaXT3mAhsM
 38.1188 +BQkB4TOAAAoJEJuTV/46XYOBgzIIAI6QLoLTUfCba6wcHDorwy7Ohtt8iMxu1wL3
 38.1189 +0wIntSr+zEYwuEO2zcpUQA+uro7PTiBj00bJejBG15ZPEbHVPT0sYSKAJRmc79nF
 38.1190 +T6plCSqUsorETgMw/QSGf/elW0jmuVjsxTeKnpTqQZ2TjM1X5Gii3fttakDLTR7F
 38.1191 +Lo3iP5Gs1TMsphRUl/XwzgzwBCn7X5gKBJOFcAskaYGDPKVV/ffxB+L3XdEgRQTd
 38.1192 +pzq4lyosM3CsbKd5dz3fVEDYcpaQljhOO5aJw7oXZgl+a86FxWKMunN2cEFOJaeD
 38.1193 +Jzlv9PIEdyB18V08s+zxXXFQjdNt/5r16/13bPU5ngqclMiRb7eVA5gEWl0+HAEI
 38.1194 +APcMKxHq+qljF5i7ESBoATO08KpIDy3V2u+wZaC9EXDgCRV7UcN4XcQz0DaNitJm
 38.1195 +YQB5eC3nPU1q+NvBoRZ2HTuMKyhfuVlMwxN1HQhMB3DE40XhJ3za1OW9wBzuaZQI
 38.1196 +9rxTExL+z8q8Dswivzuh4aDAeegvA0kvlsH2jFqGGabdqZLckkGSEtKxSMbCyuzy
 38.1197 +J3B9dc+YEH7l4UlxqJsTxSVSzOWjUgmoLuXpTLQjJzyEACgqRA1xUuDe1PYgoMOM
 38.1198 +k9PHHvmAa16VIUoPztXOZFPC7KHznEt3atPiJbaLvaOrsKe4KKXgFTFJ0RI0fkTp
 38.1199 +SQTy2BCcYV/b4+SStFh/E8sAEQEAAQAH/0woMSLN6EXNaVnI2Se/SBeTgNlNa3h6
 38.1200 +w4o+O6YIgtbkCYjYwkTa1zUDr/0RNylTLDYEPBsSfOBfyKWeFDWjZbGUrT09/Rpd
 38.1201 +Qom+AZwsK+MEnvdMyGqB3z2PeCizClL7TGyTw36IlK/vtzQQxhjw92ghzbLYw0+N
 38.1202 +XxEeGvhQ/JlmgqvJDNRJNSn7Umza2HD445/l2A3gaJ+vUee4kNnIy1c0mOGtD+7n
 38.1203 +RMSxOhLk6/QrmrPUdk0X/7lmTf+DFg7dolSbM0Z4uHE71hPyceFzPrNsekDK3BPw
 38.1204 +EfI91FBlbDhANNEbtEjJgX5doLdT7Zq4n9S8nK9O0PtTJ9qvf/adtxEEAPcuQpYT
 38.1205 +l9NCvBCIPQF+hRNHLjjIfmbgWx1I4HkmugwJL/m5F+bHA2WXav4myUKhwyqPVkYx
 38.1206 +aS1D1xK36EVlawtfdQj8Z71ZZ0gCGeCeYeFNOh9JoufItVS1L3YNfNrjD6UlVYLT
 38.1207 +elW2j+Qz/itSF6WoBLyuHjtKOJ9eT1IBNIiZBAD/3LEXA2n0GhHgkZSB2l6TO5Ni
 38.1208 +vccaJxbxEuWLUU5RN5u/MBFmA8qDYutyza8PLd+nHOMenuN6bjwJLgZpaIAFZCUu
 38.1209 +FMRAXNYR80Vrmed/lUZ4tZm+oAb09HeUbT1oQyHQ3/T40C7AJxF4iFe9RBCe321V
 38.1210 +w0h7Vff5Pus4mZeKAwQA3iLP25tsSOQQygrAGL8E5FAzlhyMA48pVG05y1PG6FZ5
 38.1211 +2SXhKqYkzYu0M4kjtCWvKW1mAIWKCXK93L0gFIO2l52JFIcN9SwqcHIrk5BOL7DQ
 38.1212 +e8Tz45kgPuSoQ2m083lXgXeTjYrmOLOF3pTiomCEugfkQWVCDpmaV4eOZHN5S4c3
 38.1213 +irQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYu
 38.1214 +b3JnPokBVAQTAQgAPhYhBHOuKKWD/+Tr1Ltis5FXmxJzBDLNBQJaXT4eAhsDBQkB
 38.1215 +4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEJFXmxJzBDLNtRIH/jEONwd0
 38.1216 +2tYIyRooWAFunAjsaqFrLxslagwDlyhVNtuKXnrOtsjPUKTjI0zhveBBURAgzcNg
 38.1217 +n47VLo7F2YeS8be7hJ9lfcQLyZhVfOKZCm9dnT9WZM5zOrSAS+4V/BPR3wsdQ86Z
 38.1218 +QvfHbgNPKnB02k87y0wD0UR/iyWt+yURH07ePaiMnz2ED25UM+YjbDPbp6x2MLTh
 38.1219 +Mzn0zCzIjW86xJm1D9oWf8cIVBFKtQRweaHLFrVQZG7IDrl/E/luCpEKikTbHZdi
 38.1220 +immHijsOoodQoviPlfon8itdnO543RcNVCEz4W7WatQw6zQbY3VLien6YAChOqfu
 38.1221 +pHuu1HhTWHvIFWOdA5gEWl0+HgEIAMAiyTdm6ku9jeNkfeVlKawMzzviJ4eQuq7S
 38.1222 +ltZQP/vPGcI8orxvvT/0yF73Wx1yoP3AXeHbjTv1TnNqC/bRVfDcNShlyy6/aRi8
 38.1223 +Z1wv81PwtSlKLCq6ZJSvG6MFt40Oi8XY/zHwEPxyeAKcYTwP0rGZ35G/KDDMG7sI
 38.1224 +h/ikCN5APJDxEoFGj++O4h3kL0oAXzSJYGQx2J4vlmKwtM+tQ/EVrVOY3hN9Cc/Z
 38.1225 +xiQsNja6gISDHT3Ucg2+HvqAuhTUuzYwujCP4Wt9OCzerHi4SudgN4G33EueTToy
 38.1226 ++A6tOC/7JH+15LnWbDfwGJSmRufmoeyfs4uxpNM4s4KlZentAE8AEQEAAQAH+gNz
 38.1227 +PHYXDi2rquDCnQjMVGoSACX8+CUU4hKh68fPwMO2otRG6XcvxyVfBxAUKgSGhUHj
 38.1228 +5+ur2RvoBO9z9TYKk/FTdaLoPQn1sZ9E7Cg5djRI1hVL5IIklF91INkVu7I36ND1
 38.1229 +22ib/STDW3NUjTcaY6KrzC9zpXbxhgKe8xjHEp+xs0sK+LyOtEoUnqvUOuRmQhSG
 38.1230 +Kw9qgkoVuu7gidAMl0Cie0QNFUIwgyYuvAeWZsDG7LzIoIZ1MM0Geb4o1HXkPHau
 38.1231 +QAGeuu0p9hfyrCD3HEcctgPxYddVIW34/eXRYhQRQ8nyvuhVKm6brUoCNz+88+Vs
 38.1232 +QcAmHK+pPX9zCa4+dcUEANLP8dc5NhR7wYxfRv0jyc/HIg1vkDEnoRf6PxIt5/M7
 38.1233 +d9sy4biL6vvzBTukbkbp2rxsSZV8Rq3CpyF/y1cL/MoPa7yT9J5XaO9KGTf6ID2b
 38.1234 ++yKFpbiV192Zh+AM2RG/3QLttN+C3opy/Ine60hLCMTph5eZDW+e2pa7XACWKATr
 38.1235 +BADpUf9jaPYDRqXC/lYfjuwrHppH6mRySsq/GcaTrPVcVat5ed1BmsNljvqQKEW/
 38.1236 +CqtNGFOjuhMO5XphcU1z2F0H+WdWnGj3LrcWnoRS0cjVz7rVr3LzzlzNlFKDeTq9
 38.1237 +Tsv4oLdYJnTCv2FvF0r7SYs+fnA1YigtbDeTEzvz96+pLQQA1cgUyC1H+/jZ0GKA
 38.1238 +hEgXGO0QhvJSLkBHxE1BZKXhoLuTsgmOTkTAuZA3tgVdNjQ5fdkPnqQEavJ91r+h
 38.1239 +AlAEaf0DQS29YnqUqwqs0tB1MXANZ+Iem7GhA2wZ9e3TrpNy/vgH4xk87V8Vf+oV
 38.1240 +0VkkmxK6Kh+5zCSPccWqAEtXBElAwokBPAQYAQgAJhYhBHOuKKWD/+Tr1Ltis5FX
 38.1241 +mxJzBDLNBQJaXT4eAhsMBQkB4TOAAAoJEJFXmxJzBDLNxGQIAL0/xrCtb/ehDWWM
 38.1242 +BTtOy7GlYEQwYVU5mS0zSjipUtr9kvoriFcOu78b5Vo+dPbMj0jbmEURhYbplQGZ
 38.1243 +ZInVChz/hXQ/QwnQaLaLBJHvJ0RBeOJFkHwX48ddRXg1c/JzGfbj39xx/Fsh4wQg
 38.1244 +ANl9P+3BH8kAeQdKg5Co/90FgICxTSJYJ1ugRmzSG9EOsGPGS62L6p8WPxSTPGTZ
 38.1245 +VsYeXoOPeFYETKDvch3jgVlFL2FjwslrGJemKspSg5Yrw5Amfng/0wvdv0E3HP0y
 38.1246 +p9cqyhenGu4O16kzl/vHtm1Kv9fBBK8kMhhq52HqHU6hzScWriDPuBf4heoPkbiX
 38.1247 +4lLaVqSVA5gEWl0/BQEIAMT3qCU5JYO2v+B4djovl4D3bb4gE9CUc4MVLfRin6AZ
 38.1248 +nPcPXcl41y+jtCOXgbG1MhVRGPZMiqaVtA6CP5r4/lAwV2wJ+vw7cJVWoc1e0JAN
 38.1249 +ZsuZW9dY916SCKtiUd+ZkEfkPjcvWl2iLQ6FHTogTebxf1OuIbkqw8elZ1CG51mb
 38.1250 +1qTReqeyElfSjBF9Q0nG0kjtyCzNzC0TpVZLMV9t7yCCWvosNHZKck3j1WUFGPTH
 38.1251 +AyHht/wpjwIaSTcdlkrGTXiSbp70VcIUSFeA2ueP0Sc7Eq+JZ8XBWiaHL34YI8Wl
 38.1252 +K4SmiTPAoOAyAmhU4KVaivtfvUpVGSbGQG/8RLCWSjcAEQEAAQAH/2IDCKlJKAlE
 38.1253 +UXOeDdrDXuT+ep3+sU176YUDb4Qp5VuSE0D/ZQCBwLaEg/moBRIMY7kmy0CYcvAV
 38.1254 +E22a05LGrynw/DeXOcz0uP+fBdG/ihH8kTfj/scIjsOA8I5z1ODqtdiIU4s7ZYCt
 38.1255 +WDVe+N25QHqYlm7p+f79sEFy5Ze1IX89RHL6x3p+ga1cCs79sWAyxKNBOgsb3ctj
 38.1256 +koA5wcx7ouvo1Ju4s11lZWfNm/ez6IjKT+HF7sJHZFnjeKGWAaYkwqVCvEcDW+nt
 38.1257 +7cjG2FRxUInOfoo4nsjoxYJgz0bZf3HtQ4tRBv/SC5w8Wpm44/xECwbd3MT9IShE
 38.1258 +xPTZmPhkSHUEANO/KrzwVk2oj61cXswAAB8dqaE13Hg11QSjM+frD2zyeUu+CUbX
 38.1259 +4N6nPKD2TRsBglw9oYd6uuAePFbxMJOIP1sGc0aSRD+excHxvVSan6pLnGzUKicp
 38.1260 +l4zkue6vfNINzNlW4kV3Yf2VkWVz83fgw3sZYhri8Q5k2OQs9iF2zCRTBADuIcTJ
 38.1261 +iUNwmLfea7OzBAUf0hBcCys89pweOfiu/Qe6RIULytLEb94lkqq9NlRLlMlw5xIB
 38.1262 ++h7xIkyikVv28skhyfbLoDAn3miZ2iONfylEuuaUHD4/Pm8XItS/qWNDl7mhttm6
 38.1263 +WLGt9hxZkdbyDyMmk+tm1tyIyThslr9lF1eGDQP/SdK3jMYF/3DX9gJbAO/mSrhb
 38.1264 +0ReDK1NXwL9TPTgWV4imsXsJI/R96s3eXS7CNLZLv8Yco1xJ1UL3tmLGj9GPCQD/
 38.1265 +8niDN7HXCjr9l97B1AcLW9B9f8uhqqqbiiV6GJCEPz/b4ZnnYTUHZgWrDEvDip+e
 38.1266 +dT7xkgm1OnpfJ84ZaF1Q5LQxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5y
 38.1267 +ZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBG4QYWJa2PRg2CmFeQ20ZpZD
 38.1268 +8/GnBQJaXT8IAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEA20
 38.1269 +ZpZD8/GniUMIAJyPOVIPG9MFxsvjh7hhRUKj/zUABH3+SX9gLK5m0QC1lwdVK1FC
 38.1270 +uYOWIzeHZ+AnlCBOLq1Wg61aVSr5oTk1h6sbizWe1cuyC4F4XnltzhOoD6RYmgeh
 38.1271 +LeZV4U76nRIV3F6icFgY/L2Zn2s9a+XtdUUGhF91xhM4UO4a1B4eu/wXH+ZhKLIT
 38.1272 +NxC8Ru2RaFqIErPLNQZhSfAjtAf9Tx6LTqWOxRscGSgri9YM6re57sTZ4bQto/Ny
 38.1273 +81ojSBcNuTUDC9w4/5IyOQQVz3Hx6waU865H90gJ/p6VzbxnCJyE/73jL+YSM3eQ
 38.1274 +YSAtqNoxHR6wFskBgSna1d2NNjkDA22gRhedA5gEWl0/BwEIAOSCc032sIy2qicM
 38.1275 +3wx9IPu+Oq/wTQDm4afaLArI8UuQNSS0FEk8f5DW5CpcI33KNrt7ja2ph6eKeg8T
 38.1276 +7HD28I76xcNPSYLdAKpwpSsOIdWm9tz9tVZmrsXZMeian08qxmgPIoPD430zuCLI
 38.1277 +D5coB4L3Wyb9SKxNWcZuM/a9e25/lf/HKsmXAxS1lxGyzN6Y7X+0b+zlvuKH2tPy
 38.1278 +J1zxtG+x4yNLc730nKQ+4WIRDAUCvfDdxktUHbqPdJYu3ZYJWysUjvHpGOg1cK6l
 38.1279 +avsumYzzt3VTfty5iCc5z7cpCvxnSC77IhygBSGD73U0kk1hyDCjH6n2BPjDgAi5
 38.1280 +ppyECc8AEQEAAQAH/jQ07Z0JWGq9rQBA+5DB4dBCNOxPbXhgR3vu55MLN72407tv
 38.1281 +/RaCYO65eeWHqYAqu/h3kPX1Po3zoFFjjuh8MpeoCZjGu5fPYECQfdvpXaePfuUc
 38.1282 +fdqgmRuQtMtc0DrpHe1WT99k2MuZDl+773vsZFLyqnus8HaVMYaZVPvxbIrg4tvd
 38.1283 +QfKnXKQ/6CuGFJIx6NGE+oZd2HyIeNW7Xa1y0SZRckhszaRKRsWSr988+4v2yUdC
 38.1284 +XMCPew4Y2lALDeueXO9coYn5hJ99rH2sXew8JN0oDzMEXA8N4vSYi7Vs9BO07FQf
 38.1285 +2HjkeM31Yowlji1A/BhuQ4db7gffxYd58zRZFxkEAOyPFlX/DwSG+VxVUogImLXM
 38.1286 +AHcksZa84qkMwkZ9VS4D4hocSuIne9MJU5yWC/+L3VX1JljSRjadhoLceMwtRv4W
 38.1287 +V6X/+hkhT7a4oa45k8A7pha/h5PuZ4AxbXv9yQwS4dE4Gk5dgSX0zQMJTAyAQk2g
 38.1288 +K1WbxgMM4Mb1BTEc9z1NBAD3SgOr6aStxl6l4M5xdJ9pYTp6BAV3Wl/gCB6jHuXP
 38.1289 +xFCfDiohpjPvYD/2PEi0/I0mOclPtSF4BX5LSJr4HE/NIBBY3yR8n0/Mm74W2XjF
 38.1290 +oh/IkB8PrvDvPwA2a2qay54v31UC2sBCfIFMG1foLuaFbmL3HRayVhBq4tlt2cBF
 38.1291 +iwQAnM4e2HiGN7szZQYza8zg2xi4DdgZLTuqe+sLFoA8TZJ8kNVzzD83MVz5jBNa
 38.1292 +8Sv6DxSFPTor3J8Mdot/yuW89Bd2QQre3JxMzFdY2wzeVwuCJ3BZudUmiT0GBu2w
 38.1293 +DUl4QlOYssDwxtzpkg59W9X/bjZh8AwxrGXNY+/P81VHKwFBcokBPAQYAQgAJhYh
 38.1294 +BG4QYWJa2PRg2CmFeQ20ZpZD8/GnBQJaXT8HAhsMBQkB4TOAAAoJEA20ZpZD8/Gn
 38.1295 +0fgIAJF3UOFyHql4qU7nQzgRk05thYAtdS4nqp60tH4JFZOCAKvAG/4DznN3zhOE
 38.1296 +vKdA804swa32V6tq6EHt2SdByO6Mx+gR92Dle2mJ5n+LHaZUOkVcwr+iKpqemrDZ
 38.1297 +2wvfzATnj1wTUAOKgStjh6M1shzxSBQlhi1JrXuzr247BfrDatUoFwJJN5nvttCT
 38.1298 +5/CJ+0YmbJ8E/HEOO3ZfMLb6KDudd5nLqGhr+3awT8iHSWeJc5L+GLTfOFBnaukp
 38.1299 +ViqE87bEPUpHqOxpkkMHjCjf8XNrbCGqhnva/vmVoQo31ypvyptDS6HoFc1F7JcF
 38.1300 +ZTgzfSrMy1QG9Y9RPO2pXRvQg9WVA5gEWl0/iQEIALzY8Rw/OENLadJpABrqg+H7
 38.1301 ++8HDg6NLh5HcoADrp5he+WJ7scJ1AgSEvFq6/CRbmV6B1O6KIl+CRO17AIL/advm
 38.1302 +z82GBwZaEDLVOK1udMAPMHQL/SAIhakmhZrj2cvgUM8DqkraXD9smilAhM7ABA35
 38.1303 +lYXQzCuGVXM2bXGBEd3kHvEsTUQYgWpI21bjtUbCiIx4eIsJWoo9LgJh+9lrRZNZ
 38.1304 +I8lE7GciKqoV3CfdIbcEOlEvYd2uBBvOoB2KjsmqOS5XvwV77xzNiSxrtkf7WF2K
 38.1305 +q3t10Thtl/0grK5RgVj9GTaJKpTQGnS9pxytcj7XAsbq1JtZWJRVykntd/sjzdMA
 38.1306 +EQEAAQAH/RFXcfYFlNg9Jce6zlXVFkJGHk13SPB8YEPT44+Mvv7+LbQjprm0KU4a
 38.1307 +laSr9LkuqNaltn98iNaGGGf0ZSIia+lTzd5SLJ/33PKbY5Etik6+tlTZwFH/kQKX
 38.1308 +n9TkOoepyXyRGhi16kWwETdbjjaMKch8vwR4SDTGU7TOQ94/Ribpgi8WHV+pNrjZ
 38.1309 +rS0epw83AHuBMIbkRwncmJelCoaooq8O8VJlV0fZXzD5z6+6qJiEhBPFfRKhmKrP
 38.1310 +cC43D1NgirAkWKd7jAvrRlmeHvuXJ9LAiUdT8NqYfiovALrR86NI8O8b8+erym+P
 38.1311 +Cg7Tyg3Gkn910Pihc0d8fbV2dZTWeZkEAMsqxqMqsKRmwkGn4dz4um/vMlREQQ8W
 38.1312 +wQ15zm1tRWfNN8UUNPqKyVn1W0KtgpmcIIKVKsXMKm1qjuhdTFAos76Dhexjyoif
 38.1313 +myR5CaQMSbjPUW2fH0b0Gbq2MdKezwFuC1WWya+8dfIo//dkZsWaDGNFfOQ2CJxE
 38.1314 +VOSo0ODP1av7BADt9ODZRrRvvQQ4eqSt6+Tm34T4AytwddGYPwBgCJL2HI4JvNb8
 38.1315 +c6Ba6wHSgV1jnw6ZVDOXnjx88l6xXR6jJC8AjCJZOo0khXbBI9yOBDf0VmQ7YMU3
 38.1316 +RiKH1t/BKYVjD1baakLr2Us6qhkd2VWhqor9LC8y15jBjCBaP7bNdpSmCQP/UVSq
 38.1317 +Ly8+cx7TvsNSRNY5erCa4A30NjyxxJ+hEWo6aWM3Q6SjQhH35FVz/DmDcaIDJRjw
 38.1318 +7ZBOqwgSC03TYOocSi2qGoOSHMYx+sRVA/jz8G+FWrOUeSut1FQJpQ0oBvHPNZUf
 38.1319 +b7vVNHHiQ4i4/Wz4AgUMPBiYE2HMgEQuSXBEJEQ9ubQxcEVwIFRlc3QgUmVjaXBp
 38.1320 +ZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBAWx
 38.1321 +BI8Yj5OsTUNw3DMS//Xf//neBQJaXT+MAhsDBQkB4TOABQsJCAcCBhUICQoLAgQW
 38.1322 +AgMBAh4BAheAAAoJEDMS//Xf//neweMIALrA+cRNEtZcke/TQWgvIs8X5TUap5xp
 38.1323 +5msw5JoSV/xG7jB77RFRS4/GwXHTISclrEsCvMWPPStZ8/JuHQ5RoSI6i9EbpDIM
 38.1324 +BeE2jXpX/cI0vJ6cut7R6dRQ/wg34huaR+/eLQjdpoIiw63S6a/ERZs1RBbp14kQ
 38.1325 +LBuGM7zfjaa0TXSnZZSFgSIqCF4GqMyBbIm9TT5NTsda0IjrpZmCQ3FPVMYlFb9J
 38.1326 +PRvTWLH1zQPSiEliF+GAkTNc4jGQ11qU5bl7CTrLW/WaQkpOtOZciO+guKvz45XU
 38.1327 +dmTuS4Gw9OcHoiK2fIG/o9tl5G8XhugOlxKaeG3S0QKdJ1Gm2CNQ7ZOdA5gEWl0/
 38.1328 +iwEIAMivUQ9kPE0Al7/4qipBRRjnc1cytd+s6akEzlkjxn47NjnCixd3lS4wXsHi
 38.1329 +Kh+P2O1+7eVSXgKlC2VLz54C16jr+08xvjjjTBGcqv7HSKLBYuN1ZOJ9uQ8Tjoh1
 38.1330 +2w83eWOU8BopW9PTb16gkf9pc2RJAUXMyh7xdaSXEffXEUbKVLam4N6kZbIc6aLh
 38.1331 +OxoGRIbBIL2yvyHxFItgnRJrg22oJOoYkRWonGga2YT0BtlSRj3Q5+E7/XGveFUC
 38.1332 +vtGg3xEvU5Xy9xbMxkSDmN6o5GtFOB3JZp628OYWNMbGDaCmqFNWBIoQMw7PZGlD
 38.1333 +yujQ3QLAXbzsWPtkCUzSoBeYp7MAEQEAAQAH/A5bxM/2Gv5jaXgZwYsOanQysyTt
 38.1334 +AuhDBeDK8Dyee6gyclnFmpAORUUtvsnedacWcq3jZAABWaqUxnDz8KHckDOM1sk+
 38.1335 +xN5rHNkxvWZHOeIzNfESSCqQVjpG6u7Gh+rZzDycvmUQynooaZJ6qJd+ovvs4UNu
 38.1336 +OJPoMMOa73UtFRZcaRLJwS77v02vrxQYVn4Tlob7VPrU98qiWYxtOYm/MINduMld
 38.1337 +0xRTcfHA0xPG+E66JGPgIVx/fSo+sitEfSnqyoxdjln8vO8eFvwCczmds+WKjBSI
 38.1338 +Oc99P7Sc+fLjvCBVr7h+UbIQ0WLI4xfemPGtMj95FKQHJmSFlyxO/QypswkEANEK
 38.1339 +EAj29vLJCiMs3hpBtG4ATlAmd+DO+IOgHsfQN4riZUVboqhsfZZJ5n0kSfpL0m8m
 38.1340 +F24hQ3acGhjGJqWBh0ntqho7dk0r9+nBWde11YeGUNaPUNCfTyNu8Mcr1inay8Jw
 38.1341 +Jj96B80CDEW8CxujA+TGxuyIzcbd6IfvoF1o+HmPBAD1xMja0BiM39jqnZJNGYCz
 38.1342 +71W3oakeORW11oXqf3l1C/xFwU+A66MeutpJdF7rpeERrE5Yd3nGBClOMtRukcf9
 38.1343 +rmgV1iRG/1u1JLBEE6V5b0a7eLmlPte2puFe+xj/4s0VDGeAeB58PMqpJSF92TOr
 38.1344 +Kbivb9vU52D9B3jVWHy1nQP/fR7T11hOYgPAz10HuAklEISF6zDm9an8zqqmE22r
 38.1345 +9HPNc08p3iQ1MdI5AmDU7siVtDmnPxHlzWTNAmWAYUQfheSEC/H4HkBxlmuu7jWd
 38.1346 +wvq6N+LqoQLuR7KfxCjECuWEpRFJh+5rgd0f/MB2G8LanORVANZk5Vqa4BcR47qx
 38.1347 +T3FMJ4kBPAQYAQgAJhYhBAWxBI8Yj5OsTUNw3DMS//Xf//neBQJaXT+LAhsMBQkB
 38.1348 +4TOAAAoJEDMS//Xf//nePXIH/1K2dCX2ouVCK8ih8UcuSnT+PZ+lkIV1zCFFqsDL
 38.1349 +HW3cm0zWkvwTyDl1AIE+XrbcjFFyDn+swP75FSaF8jPmSIgajvjAhx9gP8bMyYr5
 38.1350 +joKhHLCSCWa8V8trkq0ykp0ULCItD7e1uLCeELoOpFLsjhPJ6gzbUT0Haxwh5/vV
 38.1351 +W8dKYSEKvQ3GoBxFVNtJmkPpDTjS5HBMeI6hJp4C7rlOjecxgOKjlQvy8GkXIfTW
 38.1352 +vaWFogBLZnVRUz7Id1BFYO706WJcpYMApr8JH/ZncApAPrixnN+Q0o91Hd+IujaZ
 38.1353 +RwETuvKisq/hP4/qpDcUrLNHwBoo/AMPH0B07pH+Gse5S4uVA5gEWl1AugEIALjg
 38.1354 +B8p7KNoH+qtHcYeywtNcz4qN5OwvY/l27UrCGwWZqLkj/zw0bqPnrHOwZwmJhEsU
 38.1355 +LkLvwsZScMLiJBi68V7cAYsa508DVGTl+jJp7+jCTnAkUF/fP5ldm/fbmipd0WUb
 38.1356 +giHOUvq3TAtko1XXRzRwZrFKo2jcdzHbvCtg4k3fXc7VhLtC8+JaaDKmdqRPHLOl
 38.1357 +Ivd4uYihMMX/NK9W6mj41nVZLrloxsSwtpMEy2NTjCMx0N67lezQe/DNN7hPkq7J
 38.1358 +NB8vfPlKiOGxsvxyVHDxJVsQukEedANOZSwF5g2+WwyzEWWpjBA1S1CGeuDq+xlA
 38.1359 +bwnjTw9fhZzW8INg9/EAEQEAAQAH/RAn6nZhjz8yfaTp1ZGIEn+EYlICNr8Edduk
 38.1360 +mXW0LcauWBt0elxpW+vbQJZMPveLOseRiBNrFB3fBsyjv4d2ZXEmj8SiFr8FvvfM
 38.1361 +Tdze+3YJ7kSINTU+SLa0gqnv2R1FB+9VLpOZY2YBOQDb4Ww3J8P840nbXcQO/s7u
 38.1362 +xsG8XI/KbwAfb4kd2F9jFNHyw9Jv3EecI3NMzqBnpuAy9uKBOwIrkJDTsvxBvm1p
 38.1363 +YJ6w34LberdQQtDQE6/D0YqNue9VHzuKaexm+60Se6E8ZB7i4o6hq2rasahnwuBR
 38.1364 +beTAjrLeYunfoGVqrb7MF0PWh67+qfNKYunC9u5uNP65UYqTcssEAMk4xNxcotj5
 38.1365 +Fs+tWTRoj0resayLZjnAwtRdXiJT2jWNOK+pGdnk81JUFszepVeh7C3NYQqQKB2D
 38.1366 +UqL/0bTUnzx49VMK/1IfPB2AugNiAiguxvnOY7YcEghCPogQcLgWjEGbn+JxQh25
 38.1367 +pJz6TtNcpBDRCHlJ4PgGnLv7jAtqlHDzBADrNA6w+M5NYZL47Z5aeUUHUsDUnwDD
 38.1368 +p42yM16m/6W7enO0jxJ0Su5s05qW5WxS75nSvcWnVaLJjkORevyjANC2BAxq+/cg
 38.1369 +riPBGiXpT/+wlRYqPqX5u5ljxZPs8/WEHJ68WAqkKWBxd9nfi9+Dkeje04QkBaQg
 38.1370 +sSyKufXA26LMiwP9F/2LnloZ1qjwxWUblCYnsi0//QscelMOQDOi7KXMBNEkVpkS
 38.1371 +yWkkSFCT4tn1MbHx3baeJ1m+dcpsYHZgMQXcSOziTBGI+H4HpUDCcSngmat8bjtS
 38.1372 +7GB9FFHg6qYFD08mtEhB5orydZJLCCavLMOItCRIZ1+R6VrT49wzI5TU+FtRS7Qx
 38.1373 +cEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3Jn
 38.1374 +PokBVAQTAQgAPhYhBATyFL+JlhoCwmg32sS0To4iS/F8BQJaXUC8AhsDBQkB4TOA
 38.1375 +BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEMS0To4iS/F8uzsH/1Jy38gq9ucw
 38.1376 +IMoG/M9JwSzt/sbX0qz7cJV8/VDqY7og/9vJ0uvyeHSKEjqLLwT+dDdrUxzhMJQV
 38.1377 +2tT9NHgVdUBD7IxJ8cLZBRTesT5GqxV6/kL5OQjbaGfTTZWUSu8gwD4cG486UziW
 38.1378 +eVxYHISdUqlcFlM61y+7NsdNvPf7HMPXuq0LZxHhi4iTTPTobZLvuhMy/pv431wE
 38.1379 +umTxeWlV8frVSN+2SouuwjfltYsEW/INdliRtxrSPjt+IeX67kYkzh03EpmQaAGI
 38.1380 +rKWrcJInDBr4jjvTDmLpA0jmTof+ezYCedNU0lhu2da3Kww9TWDIllydWljGHrX0
 38.1381 +TlIjZBJbTJOdA5gEWl1AuwEIANnDWto7aCVtE5+Wj+YaBoS4FeRnZc1iwqBgxAG8
 38.1382 +HLY5QcPvJkMDVyxye/pqofBRMzUY5gmQO2i7CZEVgW4TkP8t5BGKLNqZcST1EcT8
 38.1383 +wfogxCyQKQ8m9+SJq+KX2RhD6SPwn/mkHFOjT/b65on1h5h0SRn5CdRElLhGKweh
 38.1384 +5/33S+ElJYECuyyGSYkFQLWJrASyLIcg5Pm7Vw9L6UCVAUlylUA64aBFGCAW/cop
 38.1385 +oeJ/pUi9vfp7gjBLE7EiGEloG4BWdSUQIw6qhY1E04QPbECrWEKPyl1SIwiwI90D
 38.1386 +Ii0cG88Awia8NNnRwaYNkhuAV72kw8m3bfJo+XpARJWhM7cAEQEAAQAH/2LjbOGH
 38.1387 +cr70LqIdHFGw5d7lPcPQFJHVVG7CIqBrDVrO24eflW9/F9ouTxCj1dAs/6UQHn6f
 38.1388 +SetAbJK/Aly7c+/9pgE1DzNh1NiklaIv6eKteIiIGq0v1AirYCvxKvvy8u+IOQ2D
 38.1389 +sf1lP034GDL0FdRskjnCNu13C1Y3PxkjNBfGm/RiIFT+M3T1JXo4uWB1G+2ej1vm
 38.1390 +ZTVqAgfYc2R2V4F8ok91pKBPSaGP6fOyv0bwk/E8XJ8nHfjMns35H2magiTPOAcZ
 38.1391 +Mne8S60hcU/sVZYfS2G5zogeLrQfmzfiujq6D9nRWMUqEOFXy+gPi8U6ELesax+a
 38.1392 +rbMBNNyVSSOIxekEAOuLWoB35f6Ubct5u3dM2fi2slJ4LB5jt+OUUW8GvQ0sToX2
 38.1393 +uwjiOvYlrXJ+yTvdIZQmc69iKR5FaDYDhp98oWs/T8NmjwzLwpMgcccKW6rqmtEu
 38.1394 +yU63HtFgkALGLMlZi89ltj6GHhj3/62mthycPfyXtGoKH2Z50IvpFywhQMQlBADs
 38.1395 +rK/X/fN4PgvTpSO35w+J/gYSNRlS+FKByVq9I/0P8TxaZdNjHvLqtDL+y4MxeZI8
 38.1396 +/OLCK/DNFah9DpOkD58zE7VbRFR/puVn59jitdCk/TeKli2MXQBG7XZiwpu7n51R
 38.1397 +FUiZeMQ/ypb7LqpJqfo62+suv10CWw60ae0ZlT7DqwP+MA9X6tMIbe4DK9Bk79PZ
 38.1398 +Ps3Nea6wetg0IRmVloiV7DFtiPPjnCIbtUI62qBYBSaH5K+F6CC6P13eulPba/8z
 38.1399 +0WhWZ+J+kMvSdaLMq0Y7RHDF0/XxV4NtcFM90YvKIRf/tbG7JGndVqHtIQo59fX1
 38.1400 +7Je2As9i4bpXdXIuNdsaJW9G/okBPAQYAQgAJhYhBATyFL+JlhoCwmg32sS0To4i
 38.1401 +S/F8BQJaXUC7AhsMBQkB4TOAAAoJEMS0To4iS/F8Aw8H+gNSR6fp8L6luScLE9dQ
 38.1402 +qRCJ2TAamVYmAsg5QSoqYgIxSoEm6ocWikmUlZbUnpc6Ab0lhSzFjxID1cNISMHx
 38.1403 +83WQ5s6xsPXcRGzcaCOEqwCS92mhYLcNdXgw/mh13wtMzXgIdGIVrHLmCH5FQ5SG
 38.1404 +JYfJl+dHtQBDMbZRWt0eu7wu+G3uICsT37OwhgaDSWHt2D8eaQfDIHFjCIZwUg6Q
 38.1405 +X/f2JOF8Lkiz2LgIpm3jDLRfNkmJweuKSJxNsYRLzdrGlUhTArHEle0WpjRDCuVi
 38.1406 +/k0zeXEzHm4E1VxuWF9O/YjNdEWPWbl6uQ0HsxQjM92oNQqvjBtdNIZlvuY1gN88
 38.1407 +1x+VA5gEWl1CWAEIAMihMRaJQz+/1DCPhcuHjCw8UhseHo6EkvNnNe+Rx6B6o3o8
 38.1408 +mBC283vwNk7mhpivaiL0oZ1N0T6gb2qdFSszPbeLNl/fD/uVEMxsnEeSsZBEHQns
 38.1409 +Y3KuXyldNzw+SoVn9FX4GKgIPO/68JAUQjWKelrZTjw/EbhuMPqoTIQTGAq7psB0
 38.1410 +BKw4l3vEa1hH30H/IuwDK07k8/JCKyxu2KKGdm71G1fdnKF+zJiOPqIuI0xC9vQo
 38.1411 +ep3Wmk7L3NCD+6Qh9qz4PlES6pPrY/3RDKwW00Hdoi5B3y2cXhto81umEIK36El/
 38.1412 +5mOKPPj7qtXX2JYrMAXZqKS9dDy/1oPMAXhoYs8AEQEAAQAH/ReVWGeAGRHsTa1W
 38.1413 +TEbsFwkNdM/6jrhNUyzIwWlOJztw+bh2WPWrW8cCKeVvvvtBsLs31auKUyyxFTJg
 38.1414 +u/VJClnXQ7v/RNSw5WRHkWiZu2+W4hxMLOB1KNB8REWQ7kJCQaa9XsCZv01Xn7bV
 38.1415 +UCG/tmQ+zlh8nWui4Epb8Cqc8qLdeHio78mMR8cSJ+kHEYLccCBbxd9lH3qBwujM
 38.1416 +95J7p1JDJnawkrh6M0A532DU3xB60qcwEk7j5KRRK3Gv8dtD72+szyPqbkSxnwIS
 38.1417 +sysO4N8oZVcywk0uuSqQucq/cD/kn3nXevCYavxXv/DYwDfThNsA9OwcPIJtl49E
 38.1418 +tDpabFkEAMzVVSTGkFg10HIAKSRgMiosC4ZNjz8La4fm/QFFVL8aqqWYi1BZBNve
 38.1419 +hjrEr0yLVxs/FJdUZPYP+0KNNVflcXhCPObG25ruKiEPY/zH2ae4Wtz4kdS0Qnuu
 38.1420 +ZIQSetIOLs6WsFaEFSk8xjxrV6mLip6KfvjE1p06Xp1esn15DgUrBAD6vwr3KjAv
 38.1421 +H1dExbdi1V+99cWGTiozUxBHlFx2HYnUMtsfkA4HLBPdLDhB5SFaR/E8uu97xhj2
 38.1422 +uodem2lfWUDetgC2TS9ijT7I2eB55Sr5EboBeIuDvFJaA63KMJ1b64dWhI4G2/ef
 38.1423 +QfX+wFixMu8agkLt6h7YvMTIkwH7kk/O7QQAnLByiQIN+gd9W/dZv2w7WKGscavl
 38.1424 +QLn0Rn7dHfQa5vVwg+dZ/+/ETTzOj2l9FBoxp6yHo4qVIDufmDqLBEY6uXzWOM0k
 38.1425 +0s7XNDgvfLwzKIwXJ2ve8SRzZPYUw/30W/XaOdaCbVf4e3PXxTAGdIEQdgkYSdWK
 38.1426 +MqbCUmnynOaH4BxB77QxcEVwIFRlc3QgUmVjaXBpZW50IDxwZXAudGVzdC5yZWNp
 38.1427 +cEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBMIxpo4zV6IAFofXbLS83+ngSbCZ
 38.1428 +BQJaXUJbAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJELS83+ng
 38.1429 +SbCZD7MH/1PNPhfcomPoc60Hgoy3hD+ssJh+CYWzgH8V9Bu+bR4d6x5xtiLZ7pYC
 38.1430 +HJbDTG+aNxOLWR31cwJHs0ZQ8a48rqZn93pCSOsDk4QBAMaWFQxtcIlbPHVlA/s4
 38.1431 +TEvHTVEa7D+8Q7ovNr0UZwFsUl1CCis586MKiZigc2RT0OhfF4MhQpYsMjpXVy+Y
 38.1432 +EdwXGiTxtjM5RTEM2I3F2/sJJ5LevRvvTxQuclWRX6EOoPDsR2CrrfH/2tGbUixl
 38.1433 +WR0tjYilqQbXVgDjIwUlmZpf6tvzcdx3NIkDQ3IfMiUnft0k3ctF9AwjpFZMhywC
 38.1434 +qipWJhdtbewFCX3olsG0kpX169dVF3edA5gEWl1CWgEIANKRDayBYTrbaNhxtvp5
 38.1435 +WLXSDnDdec2qYQ8MbimEP2xyWeqLoSUvajV0CqFqi69X9Lss85dxUJY2J1P+Q0/D
 38.1436 +6OJI1ak4CD2o8ZjBpA3tvHTZhOV6LrkhjC1cyflmzlvRY8zScQbocxasy5pRx2fZ
 38.1437 +4Sz9LWU2pIzw0k4c9TwrMJH/4HUVqPxsb9r37SNAwZLaLW1WLidl7bUfn147m9x5
 38.1438 +BzS+18AggSlqFPS19YO1+nYj9gqdOuLqHgXobyGpVdXEixbaB8pHoQ/SFdL90Pe7
 38.1439 +V9Sg7gKjwPcEjerxz1A3Qib8cVf2OIncnn7oRQacHDfsabYYPgw9NKxgc/R+/jsY
 38.1440 +ZW0AEQEAAQAH/1tsnZpDxpqOf1RS81aHb2vqW1jH4MXaby/gfshJ4lvMvpumqn4B
 38.1441 +u0SgMKlrIGEueFT4rH8ZtRqzQpomcMVmU2xEoXhKmtFi1Bs2IGvnyAaYFyqnxTee
 38.1442 +iEV93zgJWhnlrUZWLLsKHEZBGlnTnhfKMwmcl6Q1eHa1bSp7SkMooXsR64BGTyVE
 38.1443 +yvC0gzlT/4rzxdV5AhaDESd1aJ3XEDsMJ4ZxH6WHAeCfW69MAqmP0wq1bKtZgTxp
 38.1444 +hJvF5MGEoilfLlvdWyS4B29H8awXPbDYtvD8dumxlD78DjJhYCMiYpk6+p0K4LcW
 38.1445 +BV68EK0u/jjNLco4jAyIbsheADaKZg6xvsUEAOBb79p85ECaMU2xsiotIsR4GRYr
 38.1446 +Hu11YDjOXvO5k0lx44EDqvxS4dhcUms/fRT/IncfLE1PY3SOJhDS+BLcraaXGm6n
 38.1447 +8CfrzEaqJTgtC3JqQ7rczY7BaQiMa+9lNeeQB+ohtCgrfPFA5XhymKkAL8KXyhax
 38.1448 +cuSTCVKW5vOjqyiDBADwQynurI1EDIBOOSDAl+7XIP2nN3S759hf65FapabEumvM
 38.1449 +IwGQ+AZN3OtM0rmY3xodwf3vuis824TKXNKbKs+WY7xCpgiEYj19bv5rt7o8N8yW
 38.1450 +n1mlmsEW4uUJZaJTFLbd0EkVYU8cGe4vIBgvCKv6Byv9sL10LWnyNY/wYiZ3TwP/
 38.1451 +fysnsZrx+3d5MTHmKEQvSft38pd4r4e3E3KjXKSevb8Cy/NhGuaX9HMGHn54EG8P
 38.1452 +CelvrNvpUgDAdqlG5gEInMI/0AvHOgmhA1yQcC8deETLa4SYUJzYlPeWnrLZOPi8
 38.1453 +/3NpX2RDqC+LVbaelgV2gkzn7AFJizaC4DJEoc81W7c3wIkBPAQYAQgAJhYhBMIx
 38.1454 +po4zV6IAFofXbLS83+ngSbCZBQJaXUJaAhsMBQkB4TOAAAoJELS83+ngSbCZxzoI
 38.1455 +AL/YfkKbnNcOTtJF61VVmrc5XbSbNiTkgrpO835yTM4UOo/NnqAtFtMcsZwb9Qxq
 38.1456 +0TfEyvpzpPFjePIyL1m6PLIGECshsI8bBHpbCobufVVwuanX0fDcCdJmaSGhZR/Q
 38.1457 +QUgFMXUvuwOj42WmELpuhO8sfStyI9izLCZpm3O4gavffxaANMDgQ6acVULNriCR
 38.1458 +5dreTpRY2cQb0/S3hr/wQOGlEvVokGUwjr8Sm25qxJMXXFeewjINZwATYuRWuzos
 38.1459 +ESAeA6HN0bUOYZ0y6kSxp0rPWX93Xmdn+7kEmz0qjehY/4gNHdsFo1V7P5zF/Lfs
 38.1460 +vwls1nK1PniRBlstosP/W6mVA5gEWl1DbgEIAPHlp58Y1N+IDWiwC/ujgm4z/Ebu
 38.1461 +gWScOydEM4fC8cloaXUFPqGW8wqaSKNCRTdaIxNdnlZ+EMUi9bGIXJMxsYLT5itG
 38.1462 +9LdKXn3brUoP+/PrU1552PiSIOepj/afuBVHw1hQWOv63g2zBuyt6Q4apxU3OrQQ
 38.1463 +8zKHPybZHrgqHWt4S+1+8vRlyardsZvOTYGHNGuz6j98xPpWsHyH9qaJFJjqZ+uC
 38.1464 +FscuBD3sEiC7yZELuiCXL8kZNtpe7RX4lbcpbZ2gr0jQopdfTpfF8BBX86RztQVT
 38.1465 +flDDJhK7qEKzL29jeGQu7d7hF6Ph4BMjrm0Aap9jOnUKBBnamGq8idaZXXsAEQEA
 38.1466 +AQAH+wZPTMOIJMld5aek6/MY7UaNoZeCEir7LknUbBmu+pqb2CBezibt5pIQuzNS
 38.1467 +/7Y1ajPPndk4uZxC0LDcUzndsnksqNTZKXn8fSGAUPFdIF/Y9BhDSmcVfLk+QYyX
 38.1468 +1vfrIsvTcLZbGV63HEehM7KT/Ga/xY674HQhdgK/6B66roDGmgxsRqEkLP92aBdJ
 38.1469 +u1yCpGGXLtyzN9KyAs4H8Qxrc1ecTUDP27Zd0qLOOB+k/23C0BIdhRM7Ggf8a6tU
 38.1470 +bF43L8SqE1CqM8qGIDEwLqYUQlToFivsGM6j1TFFXYXsjmBZVLb7QGgZqaPK9kDX
 38.1471 +zh3aeE8BS2d1QM0uGocHzva7aJEEAPSHAf3IKc066X66lQPRkCfNUxkFBs370Qxm
 38.1472 +VGj+tPUlqdOaUfK76jjYI/xqc9a4yZhqVJaDdwYk0TMectEDmEdM3hyo0b3XqivW
 38.1473 +zy5zKuNF5AMx1nhnq3etm1Ms5fNEtj4f7uRFpwJ7asBEX0xrFhmIvtzi1MVXDPiw
 38.1474 +iKPIHQ/xBAD9Pw4PF5kJJT4Epv88n2q/nJJRNVt0kuAqaE2ZIeBJ0hkj6WTGV0Il
 38.1475 +moQIjeelwkiYoBVYZGGIhnbKjUKTQz7J8PFMWwhVoKWHfUuKPd+Bjn52JhxmKknM
 38.1476 +VGuc/1O93Zk565o0X+/FH2Pf0XQycAtjNkyMx6VLkx8h6oWp7OKwKwP/THaAXOi/
 38.1477 +KlJHWKYsT/xnqmDQOFDGs0vBQ8FYJo4xRT5doI4PXIWxkxmFBzR6WvkxsioLKDnG
 38.1478 +K7GhrEbXK6wYVoaGbKNIruMheTbLtDvkDDhrqf+Ik14W/zBRjDCDBKqVNuCSzXdX
 38.1479 +Rhn0rnTCqhbUQsydvsijQt+YC8vSJHZD7bU8YbQxcEVwIFRlc3QgUmVjaXBpZW50
 38.1480 +IDxwZXAudGVzdC5yZWNpcEBrZ3JvdGhvZmYub3JnPokBVAQTAQgAPhYhBBYKd4s4
 38.1481 +c7J+r/gMSPd53JBfLTgNBQJaXUNxAhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMB
 38.1482 +Ah4BAheAAAoJEPd53JBfLTgNg8wIAMSaxPOuReeDIUX7seAv8LPGdsh720OkTT2g
 38.1483 +UR/ibIRtRApcsA1JMW0RJFBB0NgdJJPkpiNHogNXMhbvwHVtYJwRdGj3KW1lqFhq
 38.1484 +8x4Wl0kmIHt71bsJBLup9sz14KL62pMYHQJsPzfcke61WtLn2F8jQ5hkNAiJO+bG
 38.1485 +hlsipLEFHjPYqZD6F+Jpcesv0/J9NKCjdsXrVbbpO11X7NuOKinVBB4PWwJYx4+j
 38.1486 +mQgqFjAzh5eEjHexWg+5GmUEznBv2ATNtG0sJyt3bP+7cWFLGj+C6NiCWB8kFYGP
 38.1487 +0vj3emLowaJ490I9eRLp/CoUGW5bV5TxToUVQTRnkeEuRlUMH8CdA5gEWl1DcAEI
 38.1488 +ANrM3mtiOfcPM+/0HDCUnzRIyjVkdKzHmszdKzazqZuhNy9rq78EbmOUy8Pgrc9H
 38.1489 +ay6/PNdqHrQW0ZsJxSGyOgVbKc2SDeNHRQCTAEwYGQpotN8NbNBJo206NsQQMW2Z
 38.1490 +knTyAQUi/0AImEZduw9CPRlrNDvlE6zTSyHBlFIEcISYNBLFx5zf/3ufxLqtQ45Q
 38.1491 +SfGBOzLtA7cWJrDkJfK2Gd/Ofvq7yCRRxgb4RWZP5zYDvrNZrvqJJR2Q8T0Pcrjw
 38.1492 +ApBI8b4RJrTDG8iIvbuQizZWNNabx/6ux19qR9KsDyt8TRBUiXyUL7BQQvUo47ch
 38.1493 +CWAFpAnGp7evuRgXeS86sXkAEQEAAQAH/RDwH/4f+XJHiO2tZVrvv8pdodppHNd8
 38.1494 ++p4bjLCcTx08k/0rCz2LQ4YYev9pKYi8vo6ndczhoB+wuN2/xMpowHFGidF/mhfL
 38.1495 +M4uJlbyOTK6fr/Qo1yYMXqcs75fqfqpoI4HDnpzDRToeYDa++KVEALRddkqhCiP3
 38.1496 +Kx9hcRC6BhbcMoMJyccl2vSVraLcKWW1tGI32tRgA7+PlkrVcTuAfp7dZbnF0+kn
 38.1497 +SD/g4kPW+uEHOtUVLkQcYId1BMr/d0U0vyyd8grug7vEp1kic4FOw2z4v1V4oJ97
 38.1498 +0hqUV6+k0hPCxFgZ/sz1DsgN9of7szFtnO9As/EXVNEtvSgwpL816V0EAOROeyxb
 38.1499 ++Oy4MbKZJMMso7MpejCWukM/YSj/y4/0PJDc8hpAowWf3cLIjtFDsnzs6CJtOPNB
 38.1500 +cy5SEmnczfU9+z+K3+BdMflhRNmd9kV8yYDQgLBZmJA5apCPr29euMObGZ1ANQjC
 38.1501 +sGgql9pzJjeQMCbmBF4/JiAWg4eNnI3TxZ59BAD1VzEwRVcr3qzirS43mczyA+ok
 38.1502 +jjh0tTduUgpQtUbOFYrgXkzvBfSB56L3L+2N4CoNkGYWqj1JH4GYHW5DZby4bFYz
 38.1503 +Y8unVrpwC1b1ckdKqZM3N00TqVcW/Unpv5v27WkV6CIDj3+oEFgoSv+U1E+1XD1i
 38.1504 +g1xgduOokJ3mK+mjrQQA8pONtQQCO8Q8SPd2A7vcLsxR4PXoV9cARo6mu7Js9qCL
 38.1505 +bb/PPQn+0sYkSZZSadRsF8XZD1cvD4pfwmzCYWT68Fsgp9rGEKk96b56kTQs4JF0
 38.1506 +WfRGDbKbFQtG1Bx/RxZdzTHyL00Q+CATYSz0HAiUP8Q3cDZfk5/8QwPO5IBWnyFC
 38.1507 +/IkBPAQYAQgAJhYhBBYKd4s4c7J+r/gMSPd53JBfLTgNBQJaXUNwAhsMBQkB4TOA
 38.1508 +AAoJEPd53JBfLTgNgBsH/2K8kMoKNALxaA7wAtbaFnvNfNMIoMpHi5HUZJusISGx
 38.1509 +4wGhZ9I58xJ+G+rZG2GMP84mWnsP6Xfp7e93zpxOQ3HkYugguWGIuGDalaG0bqRZ
 38.1510 ++L/rB3za1CWPGYqGk2FD2LMOt1HeQO1AX+PTkygu97NwMxVMmZMHj3ukaoIc76dS
 38.1511 +albO2LqAk24KfMVgslUdm7xpcOtjJwow1yCABJmxr0Sjs8Ss8IYDHJjG5TA9+U9Y
 38.1512 +Nda4zBx98oJOOFTaf7Gs6/rLc28MO0GlPIjauQSNFEXPgax6u0s2taGD1hRNqobI
 38.1513 +AASv/+jbXLvKu8sD9HRp884KROo1VOsk0s7Mx9JupyQ=
 38.1514 +=PR6k
 38.1515  -----END PGP PRIVATE KEY BLOCK-----
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/test/test_keys/priv/pep.test.alexander-0x26B54E4E_priv.asc	Mon Jan 29 12:15:51 2018 +0100
    39.3 @@ -0,0 +1,58 @@
    39.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    39.5 +
    39.6 +lQOYBFpfqMMBCACz5nJSa4CRwT9IaF9HVduwwhv7Ibwu/5xEviQDczmeUYxGS3K5
    39.7 +P22aKWKiGdu9zebCBPqozLTz7bk4yCbIxuUm4+TVyJx0ORgaPswmbp5WnKhnzGo8
    39.8 +7iKLHerXTQOsFyA0eyVkEokR4GmNlyc0KK3hO4M6q71A43bYf7J0uZdXfezMoYJG
    39.9 +lcJ8UxmOLfB6GrNjd2zD244Csa/tCqjNXp2EUI4DrJWByVN18pHAeT+MmrJYkMM4
   39.10 +lOeQjeFCkPnekn8afBJ3QTaEF7yi8qrWQ0VJQpT9MSe56f5KaCbYWhv27ZzDVGWm
   39.11 +OavXDWfNgCp45jPEypAcD3jcUUrmTonYELrZABEBAAEAB/0ZeUg244IRIYwUdLMJ
   39.12 +Jt806EeOB/jdrtQx57qxwl8mS+XRDl3wXUrnyXRt/7td5QoH7yyPOm1lHQRdRfo3
   39.13 +8/H+z8ZXf1CoJG2FSd8ekgtZuFUgXZGtjwrVKCdY1U7vz1aAF+/ze6xtG5nWstCa
   39.14 +UihM/GBYrnjd91ec0Hg0jxMfEDiX5S1GkP0VVeCp5/gNgNxymgMGa0WWQArxaa5G
   39.15 +iwiVf9LIjiHUm0yOpa+5KvOiymu+zVHUuM0YnGcTM+8WaUVjXRxZ/9MMHKVz0Vmm
   39.16 +xC6Kqun95goFivIrzpsRgSBCPR9q/cx3tS+kCgFsCiF75DYIxU+MzfjTKlu13HoI
   39.17 +gjQBBADA08iS67xjjKAk3/4Akh/zz8Ok2naZGLloiMvhRJK65pCNVJAzKjvYAQsW
   39.18 +9OGTgpOTqUI/Ep4Z+ol+s3UV+/Ih1Qb/3XcPR/I2xPsrva7z9Edkg+fTeiVywYqs
   39.19 +r8ffjpDKh24sHAvMDc/UCYOhzYTGZuTxsJK4ieGyZpE5Zx3+zQQA7tZ7OEzF2Xce
   39.20 +7Z/TMYVOVf3lgGV4C9Lc4WSPHnrbW4oY7sw3dpHk1982+Q+2NyLMdPDSeJ2517Li
   39.21 +2U0KK/xv7bH3upHzSHNT0xh7iegWYM/dfQfZ4g3BPhths4jlm6ccVYqKp0qTME3U
   39.22 +YNcWpMBo4KZpXJiTjDU3klBJPAAPFD0D/1nBRlYjPPbTE2WgTjipqkl26xBLw+XV
   39.23 +I9Dci16Ze7Tfcpd3tmxNmGKgG9GElytr+rdCbAF+/NfT2rD8hNbc9j2vxNo9YbF5
   39.24 +FGL5deoXXkQvdZJP5d3PJ1XDWY3OfjO/244XzqLFhfywYdY9qS+berCvVdeQioou
   39.25 +3WyWgskv9Z8BT9O0QVBlcCBUZXN0IEFsZXhhbmRlciAocEVwIFRlc3QgS2VwKSA8
   39.26 +cGVwLnRlc3QuYWxleGFuZGVyQHBlcHRlc3QuY2g+iQFOBBMBCAA4FiEEOtn2D66y
   39.27 +JnXbhzoTYtaYEya1Tk4FAlpfqMMCGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AA
   39.28 +CgkQYtaYEya1Tk6IEQgAi8lkb117YPo+yOQGHryu37bgHn+pfEVHctvV3iuacEwz
   39.29 +kpXSyOKS5o6/0V2kuLiWTBXLIIjyQZ173LdOiDv26RlaOfwWegaw/A3QxedO0j3h
   39.30 +1MaSV/6KEm+Y3Ti8B7bvWR3Uct/5D4kkC6MTNyhcvtnnQykzkg1HaSSh7mL7rUQI
   39.31 +0RNWLQAEtsWvUNpdfZCaRwpp1Ivm830Bmg5PUTC7lJHnrg9Tcd/YVVAShk/1Y3Hn
   39.32 +s20paq3cM1So5J6SmXdrm9sp/9lnBhK+/55N3JgsRcjy6Q0ONoyVfJOV+UjugP0V
   39.33 +WmEEncrjYRKqQ7pvCyx3gFDv8vRWtHndYR00V2gys50DmARaX6jDAQgAzzSE1q5Y
   39.34 +5bcSXP2qGSg4oeVPK5Uj2nb4DF3IDF6KGmWiNBk/DWmh0v89LjvgPR5l7HcHaQr7
   39.35 +Xz48FFe3e3kNbwSckTLip6fnGZhBCQ480hMjZjXICetpc6WRbj8UNsLGkKluN4ws
   39.36 +uvtgZ5z+XDUrOwgKgwmK2KxBWh26yhCZqUYt4+l6wYbfCvzXIlUReaL+kc1lEmp5
   39.37 +nQKdzLOXKay2MO5kY4ZTQLh8vsGIS03AoG7HD4QuY6AVaB9tZ08wwoBKRRxh2/+Z
   39.38 +a12GX1qVm4aWdQd91cyaNepHnLOyejb9nyenfBWEFx171MxOQRocasZSoE0+DQ9H
   39.39 +tlI6GeSov9CbhwARAQABAAf9GvLGKhOfzTSLp1t4YXA5OVkU/GKXuKSLazRRPcaX
   39.40 +6In6WBNGf4yS9tmqT9aKufg3olLyvEco3UC/WJf17ZGXXS543GuFTe/I3yvNnYtj
   39.41 +/qBtlK/+9cdPvjI04WVD0EFxyMO4aXIKKUFjTuZ8sGpb1oAbueImVDrG/xzpu7j/
   39.42 ++yNAzTIFvdHsbuHlK5CZ52j7hWqkR7Pgji3qit6+DBMRXnwMqHQFVg685uKnwumt
   39.43 +Bld7fdxc9IQmchdAfIlF2xDQ/sadME3aCe/aJIXxka07OSJfguIoLkdYCQ8Re4gG
   39.44 +Ge6NNe5QuGpJ9d+b8Wlw/O3zZB9PnALfqudtQxLoznJ+jQQA0aNcEESsAdaTFbXO
   39.45 +1xSUv6vXXQsFS18CSKMlcM7Kx8KYwC2PkzwQns7YS98pHwWW0XiYBt+YPiNpHKfv
   39.46 +kvcYk0iavsOEoxjVb3dtyzH+BAgtKcznwnZRBLK+/dTj6RHPJ3+3OyjKFDL8QRtF
   39.47 +xMBUv8oQnAUXISiCb3vWX+PY+uUEAP0HarZ+uiYW7J1iMwSlwOx00Ne1Nz/9rtts
   39.48 +Z1zUCei85HtVZ5yHqhsRo2LZhBkghwVkd/xrcbLzBvDmAVdLDAwd3x7yH/ogzCzw
   39.49 +qZXgyrno5JSpWUj3QIebIH6vhWY3sooXzdviJYAqXOtQKq4QcWntcpFxPbxEpQCP
   39.50 +PlvM5Vn7A/4voesQWnZM68SDK4q9YCdcBmEzH8YXNfshD6svVzfhEKD9CWXCNn52
   39.51 +lyYOD839Ns7T0A0CL3/4STGNJ/RMu+N9KYKnTrVgdBXcMR1U6sgXlLZuWWKze8Zu
   39.52 +YNM38dD3rlhsPNXvHQwFwyv07SOtdsgpRy5izWdSZElhm+MDXLUu9ESBiQE2BBgB
   39.53 +CAAgFiEEOtn2D66yJnXbhzoTYtaYEya1Tk4FAlpfqMMCGwwACgkQYtaYEya1Tk5R
   39.54 +gggAo2kakClMpSC24XoBbkCCLd5UgMyb7AvqUOZgtdP+kyS1AuRHuur2OhpF87By
   39.55 +EeZs+ZxD8Hr0sju372hNey4c9e/VFMZvru+315RCF+4I/Cv5iMq6YhBCoNlL39ij
   39.56 +zto3kCZlRXg/twBPmB07D/M4k2/FXZWjqiQaN8DjXlIzXK+cVggdq7PXiyxurFdL
   39.57 +ghCeBKc+J8ZR6sshYPkpe7SmgGqqeRX2Dv+xU8i4mxXM4JAif9dOWpxoWqH49ReJ
   39.58 +Om1gWCHou7d7NS5qO6M413dqF8QWO1c71qt5OSpq+wen9Z45TOwJo8wxs0BgtRZV
   39.59 +iNqClyzhbFlp9Jpk5HhTOxOe6A==
   39.60 +=sNFr
   39.61 +-----END PGP PRIVATE KEY BLOCK-----
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/test_keys/priv/pep.test.bella-0xAF516AAE_priv.asc	Mon Jan 29 12:15:51 2018 +0100
    40.3 @@ -0,0 +1,58 @@
    40.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
    40.5 +
    40.6 +lQOYBFpfuwkBCADXNMGMEroRCUpZ3jRQ9o38NBbOlmXXQ7ZSSuXdbJU9xd+UOUsj
    40.7 +JLapYg56XbU7o17oAFfa9VZlX57OtHbdGuoUgiNS5QT/T4R6cSiPg92+riVygVop
    40.8 +ncERHsXq+7noyiSdv7peSfVygcn2Z6T63HkY/tGJJVPbfFDDUWn+qKDydpFkSiUx
    40.9 +2SDBhgDOstYMxOsDRlIEOWWYIBXKJe2tN9DSA7nDtnu1GapLNHtZRfib8E+wwK5e
   40.10 ++WijHElB/dvJdL5Zp/gT1jhtr8WxWdmbKaJQwX49VT0uU/IdWfwxfZKEjaPTKNU9
   40.11 +urrRDq+0Kgo/j9s+edYiN5cKBUkIoEFNE4LvABEBAAEAB/sHCecwrSYfy4V+hfmB
   40.12 +EmdXcd6zGBExprnOXDvDb7s7335uCyeteRRuWtItZ2Y3kqLWhLha5X5TZ3q6uQVQ
   40.13 +OwKf9BeyrOHqdc/X716LvxzgETMRWTC5PrsjU7XWdzA/8GidLjmqvtGD0sHnyMEJ
   40.14 +IW/mhOMWkL165sh/cui8FwjYlT/IA3nKO1glAAwCBQYc16ejMqWn4ghyRjmkpv8F
   40.15 +GULn3dMI4ewet4MFvqTZN2OjU7KiBTEka083Ht2yChLS16dSunfwP5M+i9wPklOz
   40.16 +GXfLAsxqP/V24tysLWyoOC6VTIJuqLzc4o9A5zdX9wukG3gEf7ceFRp6U8KGPtRu
   40.17 +UXExBADXaOQQPZ+rAn8PJTDaWFRtrFm/J9V30BuZCsN56EZ7A4nhZZkguC79vC2N
   40.18 +EoI8PzbPTSCf7Fnm3Y166ExxC1drftMtsXmKKEk3lGFUeCieiHFhFyc47nioGT2b
   40.19 +mf1kxRUUjKGq/1rCLi1lEU6z1FHpYnKu+uSEoVPTQkC/EvUdHwQA/8IKj8OKVFL6
   40.20 +pENUtACp/3ofSh+6DxDZj8+63sScTMY1LytNTn2lu9/7NyVa898ppuEq/qtrD4ti
   40.21 +o3xqT/DBhXKnFp1rQI8ySpVPjYF0KLBqdQth8YRuPeOdNAbjoOGtQsKJXzJSVu5s
   40.22 +dW4zdwFaeUxD3p+f6x/fKPrwp+PJEDEEALYhX9p0LV1GLpmGGvZIO7mBwl06I6EY
   40.23 +O4Ett+1fN0AdeAEtszomyTotCa8TDEmpVIvISebsi11eNXn/0e44jjFM9Bemdeev
   40.24 +F/tBcxbaKgESWIORf0Tgpf1xmmACG0O/yg0geQQD9v2cAhQlH5jgCBmVB2MJqwjb
   40.25 +5a6bHoBdDUIPLGi0OVBlcCBUZXN0IEJlbGxhIChQZXAgVGVzdCBLZXkpIDxwZXAu
   40.26 +dGVzdC5iZWxsYUBwZXB0ZXN0LmNoPokBTgQTAQgAOBYhBFYxvxNXMmoCqkcO7rgV
   40.27 +73+kUWquBQJaX7sJAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJELgV73+k
   40.28 +UWquzNEH/1CB1zM18gXosslKF/Kxh0xFqnXKvrc7W4pO/rYNW+qfArGp7p+fjiqc
   40.29 +5amPWO7GINW5BPw4taoAirr6sXSYB9uWYxRXL//euTcuAIyeA0Xvw9I9EL92HtAM
   40.30 +e71PNcsPeQskTtfCUGH2B8OZ84+bTSgf6WcLT9CSESHl84rA+mVXQneGTXbY7cJ8
   40.31 +i6g8HedNbzz/wmAJoByYrei1lypPnWXawBbxheDe45NmvL1AQS7psXTPHJTFFZWC
   40.32 +bswfEtYobRFX9UJ9rNGp0tY0CmzW4qRwR38P57XkgurgM7nOvlYDlVium+qv7ERw
   40.33 +Q4wsn5cSuAun93vjY9TM9O4MIzzFKdOdA5gEWl+7CQEIAOg2gQ1AF4l+/2GRwwzB
   40.34 +Rk845rzLbpp81Hlys7JQ0P/klE1zoXcSWnsBAHV9Y0utIEGwIIxKB0TAi8CFlDsM
   40.35 +/pAI7TPjIMtxndltA0JWsWtT9d0HtmyOCslk4VvFCsN7UgCrklwPSnabzbNr9W/J
   40.36 +0bpGK6sey+u0BEPAcbZPRndm8JLy+EkbbOaah97xKt1kvtcutvkPwof62bVB0i5+
   40.37 +GuvX33b5jokBjk9eWdSeZSNZQjiOtArCdnLMa5H/EbdG4Ge4b7ey//E4VKdjGcD8
   40.38 +KfW4lA6N9XZbLfJNjjLWn0XUa7BVE8K+6RDWZ0cmg4v2TC73YarNW7N+lTgwf86R
   40.39 +HMUAEQEAAQAH/AznxI3SN0yornRDd9HcZvYtrSMmci/rSpqyTXrWQ3tJPpW8XKej
   40.40 +sTwfTuF4tb1FsqJ78Z8iWRuQ0OOC+P08KGSkXlxxHcg4uQNVq+Xyr/sNSD9/t3t6
   40.41 +fG57aQvi3EmHb8QCRQjRP7vuRkUXtaUAFCQUVMZ2mHIxx7/lMNynNL0bdBtXUAsr
   40.42 +RTqBiOLq1uS1yOwdOjzae7Y5IDGZ5iwmTNtO+zVRtlyiOQ2l2lXLc8h/1n21W3io
   40.43 +f/MVKePNXDteSIJZ0UJIMRd5N4Ba8TCu/yu6iKANKbtjbrMhP/1JS1z5xCRxyfVW
   40.44 +n9DMaAG/wRiCrytRZ+bjdy4oa7d6QkoErQkEAOwFckqUHKDLtzP5SXjrA8ZTLuPW
   40.45 +4OaxmyRMScxq7KoHw9KXyvJ22aueeHRykLSjg3RNka/1L5mE/ESsZG5qhXhgJtIC
   40.46 +JGHpKg+vUmfztBdFRA38vLVdY1or7fio07Bqg9V06Nfa6eVCK004pDW5YThqOkbZ
   40.47 +tRTfhy97FDVHKI0NBAD73offmAzqGQrED0ilcy7va6/0cYnJderdFpY8MntRZSKd
   40.48 +rOpZWFAleNVzQ1F1HGOkhB4XLvdz3OI8KS8q+KgupiWPkx7NAZXV8mTA8JHUwFNS
   40.49 +4K9Dv7FpbW4Agx77+zK097B0ICki/BNDF8k3VHgbTnoSRhz2o+stKlrGP5QQmQQA
   40.50 +y6WSbOxPFrZlUgCJxDydcVGgDNEb7cFSzra56ZQ21By7LKOaKcdiWe5xI9iLdAYp
   40.51 +GRLsmmEzxn4KiRuYSkGWJlVR9o/2ZFqr6ZpGYY+WyJpqDckmfFmPFMcB8h9r4lIa
   40.52 +WDi82b8LP1Iosg5jWVYjJ1swFgwAfCjyG753jaRCzF01sYkBNgQYAQgAIBYhBFYx
   40.53 +vxNXMmoCqkcO7rgV73+kUWquBQJaX7sJAhsMAAoJELgV73+kUWqughYIAIpK+sEe
   40.54 +eRt5ZKCEH7d02F4CXVOCRY/+hJXwVVBtE86j6xjUgUpC0tb45UmUfiBMfiIN/aU5
   40.55 +6tE+8tsl419oWyUXhR/jX3hBHxxWQRrL7omqKM1pC/TYt2EH93g7el4Gmv1xUjSG
   40.56 +/djdaF15iLyNsBVMH7r5VtvAcOhhiEZQzAUXek0HT+oD+g1rt91CIG/IN9SBpd0c
   40.57 +7JgIe5m+W1rVYl4wD5JCLi371eRokrVr6pd4/tSF6KBoik9HOphNbGdx7O3P0Sap
   40.58 +mjXUGbq2UmjsEF9ObP32NdCI6srekivexxn3FUUWEe/PK3uGh9vc8vHONWo268Ld
   40.59 +Pnr7619NE1SUzJU=
   40.60 +=GFL3
   40.61 +-----END PGP PRIVATE KEY BLOCK-----
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/test/test_keys/pub/bernd.das.brot-0xCAFAA422_pub.asc	Mon Jan 29 12:15:51 2018 +0100
    41.3 @@ -0,0 +1,32 @@
    41.4 +-----BEGIN PGP PUBLIC KEY BLOCK-----
    41.5 +
    41.6 +mQENBFpctn4BCACx7hSdsA+AnAQ+VRT8vb820MUhgiZ2gBOmmjZt+R+U8jGA0RFT
    41.7 +OFGWMNwVNNDV+FFES4yTbbmH3JPEPfRTKzcBJrty0WfTrCQ65lv1GBmGPO306pg3
    41.8 +/AA8n8e7SAVwc3fHB0oImQTkiN9Jx13KvFhSm32e4DWlDEYEIOSXY5ZjmczMoLTq
    41.9 +mwbf0ROXI+aXh793AS+oUlxl8CZJxwW8EmLiHAc2KJVXubJCq3nkwtz03/NvgCYL
   41.10 +M0cXds/jNrEEpTbXjx7pnVJC1tIrCrFrKChM4qUpcWqSPwn0pIs8EP2FHS5Ou0MK
   41.11 +O59bGVWP5EPy2gyS8bfgtWt8tL0jilBlUa4hABEBAAG0ckJlcm5kIGRhcyBCcm90
   41.12 +IGRlciBVbHRpbWF0aXZlIFRlc3RrYW5kaWRhdCAoSW50ZW50aW9uYWxseSBFeHBp
   41.13 +cmVkIEtleSBmb3IgVGVzdGluZyEpIDxiZXJuZC5kYXMuYnJvdEBkYXJ0aG1hbWEu
   41.14 +b3JnPokBVAQTAQgAPhYhBPjOD34k6xkKL8v9ONSwiKfK+qQiBQJaXLZ+AhsDBQkA
   41.15 +AVGABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJENSwiKfK+qQi+OMIAIXUeU2A
   41.16 +74JwnbtO7XzGZ60j7roCAOAn5AHxGNnWlguRIk0it+7H1PPdFMETWDKATVesmNFV
   41.17 +ATQ1vs5/G3TmHCzie/yjLMKHg2ivouQhEde5x5sbI+w501GDinDLihJC1kIrBW9M
   41.18 +nEE4LniXZ1SBXoTwy9H7vLhvgckHp3JL/zT3Z7hn/oGT21Der/smYJp8lI3gLOA5
   41.19 +2eFCiwtzn1Rv09fjUYIcuvHFMl9o1yJTu/hLSRBwJliLdvl/HQLiM+onr7NoJCxd
   41.20 +nvDrQUqMVH4qjDAHJKZMjjy5TLkoTAcLeohO3NlMSXmRIhDUIr6S34hUNdrHIopO
   41.21 +RgajXbfKbM4iAL65AQ0EWly2fgEIAKnO1DQBmoB4KlrcNKXlCazCWp0cLPWB11cI
   41.22 +Gpb0DGeVEndCxQfBGRocZs7zZn1MpEpzRx9Ae/R/o3w42IaBF62RXOpofq2WSe/T
   41.23 +YI4QJJvSPJ168VuP9BmNeARL0Q1EAMro483LCCUpGIOb7uC9hn/Bi1OmK956tJqE
   41.24 +OSYqrpxkY3kw3CUVknDCd12nc7zB+1KQDCYSqQVZJ5zkagr65E26SXfvzf3n/x+U
   41.25 +B9FhnIE2zzkUJvsgY7s7z/XL/NXDuKjPbbIL6bhhP08koljCN49q0pSlB+Evw5ou
   41.26 +kmON46JSe1YymBzVA49b73IrSVrXKT0tbKVguiUG3ewc9aunUpcAEQEAAYkBPAQY
   41.27 +AQgAJhYhBPjOD34k6xkKL8v9ONSwiKfK+qQiBQJaXLZ+AhsMBQkAAVGAAAoJENSw
   41.28 +iKfK+qQifC4H/13K4LnWFOqSAXzzqnass2aY++1EVXRnMDdXsp3jU17tCFJZufoN
   41.29 +Aw7vmInrCgxMViUjfV6DfyDsrYynDWfIAS6FO3ThnFtgkgekdTrNg6DZOMl7D9+x
   41.30 +aP0S/fVITZz5XRqs7amRkojftQHJMpPNoXwcGK1hGLgPIvN4cbLIRvnGSDhkstFd
   41.31 +svNbC92z2upit7+yq9eW+Kn2exJRszgbZ53ghmhNy4CrhjJC90CsYF1SzsDlqwc1
   41.32 +ET4vjV1pCnjyVk+pNsw1V9kKMm8icFFwB57xX5Q9EdwMipNaWWg7CHMM8+Bjqsj2
   41.33 +qHs0LNWO7eQyr8Uj0BwfT04Wwz68iD57lEQ=
   41.34 +=Y6m7
   41.35 +-----END PGP PUBLIC KEY BLOCK-----
    42.1 --- a/test/test_keys/pub/pep-test-recip-0x08DB0AEE_pub.asc	Mon Jan 15 12:26:14 2018 +0100
    42.2 +++ b/test/test_keys/pub/pep-test-recip-0x08DB0AEE_pub.asc	Mon Jan 29 12:15:51 2018 +0100
    42.3 @@ -7,25 +7,733 @@
    42.4  8+q/vMDEtkThR+JIn2IeX0U8c/Trq5ek6M88ST63sU1c1Lbw1TENhch7UJl85MxQ
    42.5  zyZ/FRWlj4zoPfEwdVolLaS+hlGMH5tsNk1/ABEBAAG0Z3BFcCBUZXN0IFJlY2lw
    42.6  aWVudCAoS2V5cGFpciBmb3IgS3Jpc3RhIHRlc3RzIC0gbm90IHNl