merged in parent ENGINE-559
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 29 May 2019 16:43:38 +0200
branchENGINE-559
changeset 38047535bfbf092c
parent 3750 318c86bc30b0
parent 3803 26b82716fb60
child 3805 2e7f89437eb8
merged in parent
src/message_api.c
src/pEpEngine.c
src/pEpEngine.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/build-android/enable_address_sanitizer.patch	Wed May 29 16:43:38 2019 +0200
     1.3 @@ -0,0 +1,92 @@
     1.4 +diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
     1.5 +--- a/build-android/jni/Android.mk
     1.6 ++++ b/build-android/jni/Android.mk
     1.7 +@@ -14,7 +14,9 @@
     1.8 + 
     1.9 + LOCAL_MODULE    := pEpEngine
    1.10 + LOCAL_CFLAGS    += -std=c99
    1.11 +-
    1.12 ++#LOCAL_CFLAGS    += -fsanitize=address -fno-omit-frame-pointer
    1.13 ++#LOCAL_LDFLAGS   += -fsanitize=address
    1.14 ++#LOCAL_ARM_MODE := arm
    1.15 + # from http://www.sqlite.org/android/finfo?name=jni/sqlite/Android.mk 
    1.16 + #      http://www.sqlite.org/android/artifact/e8ed354b3e58c835
    1.17 + 
    1.18 +@@ -28,6 +30,7 @@
    1.19 +                     $(GPGME_INCLUDE_PATH) \
    1.20 +                     $(LIBETPAN_PATH)/include
    1.21 + LOCAL_C_INCLUDES += $(GPGBUILD)/$(TARGET_ARCH_ABI)/app_opt/include
    1.22 ++LOCAL_C_INCLUDES += /home/huss/src/test/sequoia/openpgp-ffi/include
    1.23 + 
    1.24 + $(shell sh $(LOCAL_PATH)/../takeOutHeaderFiles.sh $(LOCAL_PATH)../../)
    1.25 + LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)../include
    1.26 +@@ -38,5 +41,6 @@
    1.27 + ASN1_SRC_FILES := $(wildcard $(LOCAL_PATH)/../../asn.1/*.c)
    1.28 + LOCAL_SRC_FILES := $(ENGINE_SRC_FILES:%=%)  $(ASN1_SRC_FILES:$(LOCAL_PATH)/%=%)
    1.29 + 
    1.30 ++#LOCAL_ADDRESS_SANITIZER:=true
    1.31 + 
    1.32 + include $(BUILD_STATIC_LIBRARY)
    1.33 +diff --git a/src/pEpEngine.c b/src/pEpEngine.c
    1.34 +--- a/src/pEpEngine.c
    1.35 ++++ b/src/pEpEngine.c
    1.36 +@@ -2015,7 +2015,7 @@
    1.37 + // N.B. If testing (so NDEBUG not defined) but this message is spam,
    1.38 + //      put -D_PEP_SERVICE_LOG_OFF into CFLAGS/CXXFLAGS     
    1.39 + #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
    1.40 +-    fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
    1.41 ++    __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ", title, entity, description, comment);
    1.42 +     session->service_log = true;
    1.43 + #endif
    1.44 + 
    1.45 +diff --git a/sync/gen_dot.ysl2 b/sync/gen_dot.ysl2
    1.46 +--- a/sync/gen_dot.ysl2
    1.47 ++++ b/sync/gen_dot.ysl2
    1.48 +@@ -9,7 +9,7 @@
    1.49 +     digraph finite_state_machine {
    1.50 +         rankdir=LR;
    1.51 +         node [shape = doublecircle];
    1.52 +-        `apply "state[@end='1']" mode=end`;
    1.53 ++        `apply "state[@timeout='off']" mode=end`;
    1.54 +         node [shape = circle];
    1.55 + 
    1.56 +         `` apply "state" mode=do
    1.57 +diff --git a/sync/sync.fsm b/sync/sync.fsm
    1.58 +--- a/sync/sync.fsm
    1.59 ++++ b/sync/sync.fsm
    1.60 +@@ -155,7 +155,7 @@
    1.61 +                 go HandshakingNewPhase2Second;
    1.62 +         }
    1.63 + 
    1.64 +-        state HandshakingNewPhase1First {
    1.65 ++        state HandshakingNewPhase1First timeout=300 {
    1.66 +             on Rollback if sameTransactionAndPartner {
    1.67 +                 do untrustThisKey;
    1.68 +                 go Sole;
    1.69 +@@ -172,7 +172,7 @@
    1.70 +             }
    1.71 +         }
    1.72 + 
    1.73 +-        state HandshakingNewPhase1Second {
    1.74 ++        state HandshakingNewPhase1Second timeout=300 {
    1.75 +             on Rollback if sameTransactionAndPartner {
    1.76 +                 do untrustThisKey;
    1.77 +                 go Sole;
    1.78 +@@ -189,7 +189,7 @@
    1.79 +             }
    1.80 +         }
    1.81 + 
    1.82 +-        state HandshakingNewPhase2First {
    1.83 ++        state HandshakingNewPhase2First timeout=300 {
    1.84 +             on Cancel {
    1.85 +                 send Rollback;
    1.86 +                 go Sole;
    1.87 +@@ -208,7 +208,7 @@
    1.88 +             }
    1.89 +         }
    1.90 + 
    1.91 +-        state HandshakingNewPhase2Second {
    1.92 ++        state HandshakingNewPhase2Second timeout=300 {
    1.93 +             on Cancel {
    1.94 +                 send Rollback;
    1.95 +                 go Sole;
     2.1 --- a/build-android/jni/Android.mk	Tue May 21 14:58:10 2019 +0200
     2.2 +++ b/build-android/jni/Android.mk	Wed May 29 16:43:38 2019 +0200
     2.3 @@ -5,7 +5,6 @@
     2.4  LOCAL_PATH := $(call my-dir)
     2.5  
     2.6  LIBETPAN_PATH:=  $(LOCAL_PATH)/../../../pEpJNIAdapter/android/external/libetpan/build-android
     2.7 -GPGME_INCLUDE_PATH:=  $(LOCAL_PATH)/../../../pEpJNIAdapter/android/external/data/data/pep.android.k9/app_opt/include
     2.8  
     2.9  include $(CLEAR_VARS)
    2.10  
    2.11 @@ -13,10 +12,6 @@
    2.12  $(error LIBETPAN_PATH must be set)
    2.13  endif
    2.14  
    2.15 -ifeq ($(GPGME_INCLUDE_PATH),)
    2.16 -$(error GPGME_INCLUDE_PATH must be set)
    2.17 -endif
    2.18 -
    2.19  LOCAL_MODULE    := pEpEngine
    2.20  LOCAL_CFLAGS    += -std=c99
    2.21  
    2.22 @@ -27,17 +22,18 @@
    2.23  # Android has no globally writable temp directory, if this is not defined the
    2.24  # application throws an exception when it tries to create a temp file.
    2.25  #
    2.26 -LOCAL_CFLAGS    += -DSQLITE_TEMP_STORE=3
    2.27 +LOCAL_CFLAGS    += -DSQLITE_TEMP_STORE=3 -DUSE_SEQUOIA
    2.28  
    2.29  LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../asn.1 \
    2.30                      $(GPGME_INCLUDE_PATH) \
    2.31                      $(LIBETPAN_PATH)/include
    2.32 -LOCAL_C_INCLUDES += $(GPGBUILD)/include
    2.33 +LOCAL_C_INCLUDES += $(GPGBUILD)/$(TARGET_ARCH_ABI)/app_opt/include
    2.34  
    2.35  $(shell sh $(LOCAL_PATH)/../takeOutHeaderFiles.sh $(LOCAL_PATH)../../)
    2.36  LOCAL_EXPORT_C_INCLUDES += $(LOCAL_PATH)../include
    2.37  
    2.38 -ENGINE_SRC_FILES := $(shell find $(LOCAL_PATH)/../../src/ ! -name "*sequoia*" ! -name "*netpgp*" -name "*.c")
    2.39 +#ENGINE_SRC_FILES := $(shell find $(LOCAL_PATH)/../../src/ ! -name "*sequoia*" ! -name "*netpgp*" -name "*.c")
    2.40 +ENGINE_SRC_FILES := $(shell find $(LOCAL_PATH)/../../src/ ! -name "*gpg*" ! -name "*netpgp*" -name "*.c")
    2.41  #ENGINE_SRC_FILES := $(wildcard $(LOCAL_PATH)/../../src/*.c)
    2.42  ASN1_SRC_FILES := $(wildcard $(LOCAL_PATH)/../../asn.1/*.c)
    2.43  LOCAL_SRC_FILES := $(ENGINE_SRC_FILES:%=%)  $(ASN1_SRC_FILES:$(LOCAL_PATH)/%=%)
     3.1 --- a/build-android/jni/Application.mk	Tue May 21 14:58:10 2019 +0200
     3.2 +++ b/build-android/jni/Application.mk	Wed May 29 16:43:38 2019 +0200
     3.3 @@ -1,4 +1,4 @@
     3.4  APP_OPTIM := debug
     3.5  APP_PLATFORM=android-21
     3.6 -APP_ABI := armeabi-v7a
     3.7 +APP_ABI := arm64-v8a
     3.8  NDK_TOOLCHAIN_VERSION = clang
     4.1 --- a/src/message_api.c	Tue May 21 14:58:10 2019 +0200
     4.2 +++ b/src/message_api.c	Wed May 29 16:43:38 2019 +0200
     4.3 @@ -1542,7 +1542,7 @@
     4.4  PEP_STATUS _attach_key(PEP_SESSION session, const char* fpr, message *msg)
     4.5  {
     4.6      char *keydata = NULL;
     4.7 -    size_t size;
     4.8 +    size_t size = 0;
     4.9  
    4.10      PEP_STATUS status = export_key(session, fpr, &keydata, &size);
    4.11      assert(status == PEP_STATUS_OK);
    4.12 @@ -1550,7 +1550,7 @@
    4.13          return status;
    4.14      assert(size);
    4.15  
    4.16 -     bloblist_t *bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
    4.17 +    bloblist_t *bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
    4.18                        "file://pEpkey.asc");
    4.19  
    4.20      if (msg->attachments == NULL && bl)
    4.21 @@ -4310,7 +4310,7 @@
    4.22      return num_to_asciihex(xor_num);
    4.23  }
    4.24  
    4.25 -static char* skip_separators(char* current, char* begin) {
    4.26 +static const char* skip_separators(const char* current, const char* begin) {
    4.27      while (current >= begin) {
    4.28          /* .:,;-_ ' ' - [2c-2e] [3a-3b] [20] [5f] */
    4.29          char check_char = *current;
    4.30 @@ -4348,71 +4348,73 @@
    4.31  }
    4.32  
    4.33  DYNAMIC_API PEP_STATUS get_trustwords(
    4.34 -    PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    4.35 -    const char* lang, char **words, size_t *wsize, bool full
    4.36 -)
    4.37 +        PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    4.38 +        const char* lang, char **words, size_t *wsize, bool full
    4.39 +    )
    4.40  {
    4.41 -    assert(session);
    4.42 -    assert(id1);
    4.43 -    assert(id2);
    4.44 -    assert(id1->fpr);
    4.45 -    assert(id2->fpr);
    4.46 -    assert(words);
    4.47 -    assert(wsize);
    4.48 -
    4.49 -    int SHORT_NUM_TWORDS = 5; 
    4.50 -    
    4.51 +    assert(session && id1 && id1->fpr && id2 && id2->fpr&& lang && words &&
    4.52 +            wsize);
    4.53 +    if (!(session && id1 && id1->fpr && id2 && id2->fpr&& lang && words &&
    4.54 +                wsize))
    4.55 +        return PEP_ILLEGAL_VALUE;
    4.56 +
    4.57 +    return get_trustwords_for_fprs(session, id1->fpr, id2->fpr, lang, words,
    4.58 +            wsize, full);
    4.59 +}
    4.60 +
    4.61 +DYNAMIC_API PEP_STATUS get_trustwords_for_fprs(
    4.62 +        PEP_SESSION session, const char* fpr1, const char* fpr2,
    4.63 +        const char* lang, char **words, size_t *wsize, bool full
    4.64 +    )
    4.65 +{
    4.66 +    assert(session && fpr1 && fpr2 && words && wsize);
    4.67 +    if (!(session && fpr1 && fpr2 && words && wsize))
    4.68 +        return PEP_ILLEGAL_VALUE;
    4.69 +
    4.70 +    const int SHORT_NUM_TWORDS = 5; 
    4.71      PEP_STATUS status = PEP_STATUS_OK;
    4.72      
    4.73 -    if (!(session && id1 && id2 && words && wsize) ||
    4.74 -        !(id1->fpr) || (!id2->fpr))
    4.75 -        return PEP_ILLEGAL_VALUE;
    4.76 -
    4.77 -    char *source1 = id1->fpr;
    4.78 -    char *source2 = id2->fpr;
    4.79 -
    4.80 -    int source1_len = strlen(source1);
    4.81 -    int source2_len = strlen(source2);
    4.82 -    int max_len;
    4.83 -        
    4.84      *words = NULL;    
    4.85      *wsize = 0;
    4.86  
    4.87 -    max_len = (source1_len > source2_len ? source1_len : source2_len);
    4.88 +    int fpr1_len = strlen(fpr1);
    4.89 +    int fpr2_len = strlen(fpr2);
    4.90 +        
    4.91 +    int max_len = (fpr1_len > fpr2_len ? fpr1_len : fpr2_len);
    4.92      
    4.93      char* XORed_fpr = (char*)(calloc(max_len + 1, 1));
    4.94      *(XORed_fpr + max_len) = '\0';
    4.95      char* result_curr = XORed_fpr + max_len - 1;
    4.96 -    char* source1_curr = source1 + source1_len - 1;
    4.97 -    char* source2_curr = source2 + source2_len - 1;
    4.98 -
    4.99 -    while (source1 <= source1_curr && source2 <= source2_curr) {
   4.100 -        source1_curr = skip_separators(source1_curr, source1);
   4.101 -        source2_curr = skip_separators(source2_curr, source2);
   4.102 +    const char* fpr1_curr = fpr1 + fpr1_len - 1;
   4.103 +    const char* fpr2_curr = fpr2 + fpr2_len - 1;
   4.104 +
   4.105 +    while (fpr1 <= fpr1_curr && fpr2 <= fpr2_curr) {
   4.106 +        fpr1_curr = skip_separators(fpr1_curr, fpr1);
   4.107 +        fpr2_curr = skip_separators(fpr2_curr, fpr2);
   4.108          
   4.109 -        if (source1_curr < source1 || source2_curr < source2)
   4.110 +        if (fpr1_curr < fpr1 || fpr2_curr < fpr2)
   4.111              break;
   4.112              
   4.113 -        char xor_hex = xor_hex_chars(*source1_curr, *source2_curr);
   4.114 +        char xor_hex = xor_hex_chars(*fpr1_curr, *fpr2_curr);
   4.115          if (xor_hex == '\0') {
   4.116              status = PEP_ILLEGAL_VALUE;
   4.117              goto error_release;
   4.118          }
   4.119          
   4.120          *result_curr = xor_hex;
   4.121 -        result_curr--; source1_curr--; source2_curr--;
   4.122 +        result_curr--; fpr1_curr--; fpr2_curr--;
   4.123      }
   4.124  
   4.125 -    char* remainder_start = NULL;
   4.126 -    char* remainder_curr = NULL;
   4.127 +    const char* remainder_start = NULL;
   4.128 +    const char* remainder_curr = NULL;
   4.129      
   4.130 -    if (source1 <= source1_curr) {
   4.131 -        remainder_start = source1;
   4.132 -        remainder_curr = source1_curr;
   4.133 +    if (fpr1 <= fpr1_curr) {
   4.134 +        remainder_start = fpr1;
   4.135 +        remainder_curr = fpr1_curr;
   4.136      }
   4.137 -    else if (source2 <= source2_curr) {
   4.138 -        remainder_start = source2;
   4.139 -        remainder_curr = source2_curr;
   4.140 +    else if (fpr2 <= fpr2_curr) {
   4.141 +        remainder_start = fpr2;
   4.142 +        remainder_curr = fpr2_curr;
   4.143      }
   4.144      if (remainder_curr) {
   4.145          while (remainder_start <= remainder_curr) {
     5.1 --- a/src/message_api.h	Tue May 21 14:58:10 2019 +0200
     5.2 +++ b/src/message_api.h	Wed May 29 16:43:38 2019 +0200
     5.3 @@ -389,9 +389,9 @@
     5.4  //        the caller is responsible to free() it (on Windoze use pEp_free())
     5.5  //
     5.6  DYNAMIC_API PEP_STATUS get_trustwords(
     5.7 -    PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
     5.8 -    const char* lang, char **words, size_t *wsize, bool full
     5.9 -);
    5.10 +        PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    5.11 +        const char* lang, char **words, size_t *wsize, bool full
    5.12 +    );
    5.13  
    5.14  
    5.15  // get_message_trustwords() - get full trustwords string for message sender and reciever identities 
    5.16 @@ -422,12 +422,42 @@
    5.17  //        the caller is responsible to free() it (on Windoze use pEp_free())
    5.18  //
    5.19  DYNAMIC_API PEP_STATUS get_message_trustwords(
    5.20 -    PEP_SESSION session, 
    5.21 -    message *msg,
    5.22 -    stringlist_t *keylist,
    5.23 -    pEp_identity* received_by,
    5.24 -    const char* lang, char **words, bool full
    5.25 -);
    5.26 +        PEP_SESSION session, 
    5.27 +        message *msg,
    5.28 +        stringlist_t *keylist,
    5.29 +        pEp_identity* received_by,
    5.30 +        const char* lang, char **words, bool full
    5.31 +    );
    5.32 +
    5.33 +// get_trustwords_for_fprs() - get full trustwords string for a pair of fingerprints
    5.34 +//
    5.35 +//    parameters:
    5.36 +//        session (in)        session handle
    5.37 +//        fpr1 (in)           fingerprint 1
    5.38 +//        fpr2 (in)           fingerprint 2
    5.39 +//        lang (in)           C string with ISO 639-1 language code
    5.40 +//        words (out)         pointer to C string with all trustwords UTF-8 encoded,
    5.41 +//                            separated by a blank each
    5.42 +//                            NULL if language is not supported or trustword
    5.43 +//                            wordlist is damaged or unavailable
    5.44 +//        wsize (out)         length of full trustwords string
    5.45 +//        full (in)           if true, generate ALL trustwords for these identities.
    5.46 +//                            else, generate a fixed-size subset. (TODO: fixed-minimum-entropy
    5.47 +//                            subset in next version)
    5.48 +//
    5.49 +//    return value:
    5.50 +//        PEP_STATUS_OK            trustwords retrieved
    5.51 +//        PEP_OUT_OF_MEMORY        out of memory
    5.52 +//        PEP_TRUSTWORD_NOT_FOUND  at least one trustword not found
    5.53 +//
    5.54 +//    caveat:
    5.55 +//        the word pointer goes to the ownership of the caller
    5.56 +//        the caller is responsible to free() it (on Windoze use pEp_free())
    5.57 +//
    5.58 +DYNAMIC_API PEP_STATUS get_trustwords_for_fprs(
    5.59 +        PEP_SESSION session, const char* fpr1, const char* fpr2,
    5.60 +        const char* lang, char **words, size_t *wsize, bool full
    5.61 +    );
    5.62  
    5.63  // re_evaluate_message_rating() - re-evaluate already decrypted message rating
    5.64  //
     6.1 --- a/src/pEpEngine.c	Tue May 21 14:58:10 2019 +0200
     6.2 +++ b/src/pEpEngine.c	Wed May 29 16:43:38 2019 +0200
     6.3 @@ -2128,32 +2128,31 @@
     6.4  #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
     6.5      fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
     6.6      session->service_log = true;
     6.7 +
     6.8 +    int result;
     6.9 +    
    6.10 +    assert(session);
    6.11 +    assert(title);
    6.12 +    assert(entity);
    6.13 +    
    6.14 +    if (!(session && title && entity))
    6.15 +        return PEP_ILLEGAL_VALUE;
    6.16 +    
    6.17 +    sqlite3_reset(session->log);
    6.18 +    sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
    6.19 +    sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
    6.20 +    if (description)
    6.21 +        sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
    6.22 +    else
    6.23 +        sqlite3_bind_null(session->log, 3);
    6.24 +    if (comment)
    6.25 +        sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
    6.26 +    else
    6.27 +        sqlite3_bind_null(session->log, 4);
    6.28 +    result = Sqlite3_step(session->log);
    6.29 +    sqlite3_reset(session->log);
    6.30 +    
    6.31  #endif
    6.32 -
    6.33 -    // PEP_STATUS status = PEP_STATUS_OK;
    6.34 -    // int result;
    6.35 -    // 
    6.36 -    // assert(session);
    6.37 -    // assert(title);
    6.38 -    // assert(entity);
    6.39 -    // 
    6.40 -    // if (!(session && title && entity))
    6.41 -    //     return PEP_ILLEGAL_VALUE;
    6.42 -    // 
    6.43 -    // sqlite3_reset(session->log);
    6.44 -    // sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
    6.45 -    // sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
    6.46 -    // if (description)
    6.47 -    //     sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
    6.48 -    // else
    6.49 -    //     sqlite3_bind_null(session->log, 3);
    6.50 -    // if (comment)
    6.51 -    //     sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
    6.52 -    // else
    6.53 -    //     sqlite3_bind_null(session->log, 4);
    6.54 -    // result = Sqlite3_step(session->log);
    6.55 -    // sqlite3_reset(session->log);
    6.56 -    // 
    6.57      return PEP_STATUS_OK; // We ignore errors for this function.
    6.58  }
    6.59  
    6.60 @@ -2515,7 +2514,7 @@
    6.61      )
    6.62  {
    6.63      PEP_STATUS status = PEP_STATUS_OK;
    6.64 -    static pEp_identity *_identity;
    6.65 +    pEp_identity *_identity = NULL;
    6.66  
    6.67      assert(session);
    6.68      assert(address);
    6.69 @@ -2738,7 +2737,7 @@
    6.70      )
    6.71  {
    6.72      PEP_STATUS status = PEP_STATUS_OK;
    6.73 -    static pEp_identity *_identity;
    6.74 +    pEp_identity *_identity = NULL;
    6.75  
    6.76      assert(session);
    6.77      assert(address);
    6.78 @@ -5255,3 +5254,17 @@
    6.79  }
    6.80  
    6.81  #endif
    6.82 +
    6.83 +DYNAMIC_API void _service_error_log(PEP_SESSION session, const char *entity,
    6.84 +        PEP_STATUS status, const char *where)
    6.85 +{
    6.86 +    char buffer[128];
    6.87 +    static const size_t size = 127;
    6.88 +    memset(buffer, 0, size+1);
    6.89 +#ifdef PEP_STATUS_TO_STRING
    6.90 +    snprintf(buffer, size, "%s %.4x", pEp_status_to_string(status), status);
    6.91 +#else
    6.92 +    snprintf(buffer, size, "error %.4x", status);
    6.93 +#endif
    6.94 +    log_service(session, "### service error log ###", entity, buffer, where);
    6.95 +}
     7.1 --- a/src/pEpEngine.h	Tue May 21 14:58:10 2019 +0200
     7.2 +++ b/src/pEpEngine.h	Wed May 29 16:43:38 2019 +0200
     7.3 @@ -104,6 +104,7 @@
     7.4      PEP_SYNC_NO_CHANNEL                             = 0x0904,
     7.5      PEP_SYNC_CANNOT_ENCRYPT                         = 0x0905,
     7.6      PEP_SYNC_NO_MESSAGE_SEND_CALLBACK               = 0x0906,
     7.7 +    PEP_SYNC_CANNOT_START                           = 0x0907,
     7.8  
     7.9      PEP_CANNOT_INCREASE_SEQUENCE                    = 0x0971,
    7.10  
    7.11 @@ -438,6 +439,11 @@
    7.12  #define SERVICE_LOG(session, title, entity, desc) \
    7.13      log_service((session), (title), (entity), (desc), "service " __FILE__ ":" S_LINE)
    7.14  
    7.15 +DYNAMIC_API void _service_error_log(PEP_SESSION session, const char *entity,
    7.16 +        PEP_STATUS status, const char *where);
    7.17 +
    7.18 +#define SERVICE_ERROR_LOG(session, entity, status) \
    7.19 +    _service_error_log((session), (entity), (status), __FILE__ ":" S_LINE)
    7.20  
    7.21  // trustword() - get the corresponding trustword for a 16 bit value
    7.22  //
    7.23 @@ -563,47 +569,6 @@
    7.24      PEP_ct_pEp = 0xff
    7.25  } PEP_comm_type;
    7.26  
    7.27 -static inline const char *pep_comm_type_to_string(PEP_comm_type ct) {
    7.28 -    switch (ct) {
    7.29 -    case PEP_ct_unknown: return "unknown";
    7.30 -    case PEP_ct_no_encryption: return "no_encryption";
    7.31 -    case PEP_ct_no_encrypted_channel: return "no_encrypted_channel";
    7.32 -    case PEP_ct_key_not_found: return "key_not_found";
    7.33 -    case PEP_ct_key_expired: return "key_expired";
    7.34 -    case PEP_ct_key_revoked: return "key_revoked";
    7.35 -    case PEP_ct_key_b0rken: return "key_b0rken";
    7.36 -    case PEP_ct_my_key_not_included: return "my_key_not_included";
    7.37 -    case PEP_ct_security_by_obscurity: return "security_by_obscurity";
    7.38 -    case PEP_ct_b0rken_crypto: return "b0rken_crypto";
    7.39 -    case PEP_ct_key_too_short: return "key_too_short";
    7.40 -    case PEP_ct_compromised: return "compromised";
    7.41 -    case PEP_ct_mistrusted: return "mistrusted";
    7.42 -    case PEP_ct_unconfirmed_encryption: return "unconfirmed_encryption";
    7.43 -    case PEP_ct_OpenPGP_weak_unconfirmed: return "OpenPGP_weak_unconfirmed";
    7.44 -    case PEP_ct_to_be_checked: return "to_be_checked";
    7.45 -    case PEP_ct_SMIME_unconfirmed: return "SMIME_unconfirmed";
    7.46 -    case PEP_ct_CMS_unconfirmed: return "CMS_unconfirmed";
    7.47 -    case PEP_ct_strong_but_unconfirmed: return "strong_but_unconfirmed";
    7.48 -    case PEP_ct_OpenPGP_unconfirmed: return "OpenPGP_unconfirmed";
    7.49 -    case PEP_ct_OTR_unconfirmed: return "OTR_unconfirmed";
    7.50 -    case PEP_ct_unconfirmed_enc_anon: return "unconfirmed_enc_anon";
    7.51 -    case PEP_ct_pEp_unconfirmed: return "pEp_unconfirmed";
    7.52 -    case PEP_ct_confirmed: return "confirmed";
    7.53 -    case PEP_ct_confirmed_encryption: return "confirmed_encryption";
    7.54 -    case PEP_ct_OpenPGP_weak: return "OpenPGP_weak";
    7.55 -    case PEP_ct_to_be_checked_confirmed: return "to_be_checked_confirmed";
    7.56 -    case PEP_ct_SMIME: return "SMIME";
    7.57 -    case PEP_ct_CMS: return "CMS";
    7.58 -    case PEP_ct_strong_encryption: return "strong_encryption";
    7.59 -    case PEP_ct_OpenPGP: return "OpenPGP";
    7.60 -    case PEP_ct_OTR: return "OTR";
    7.61 -    case PEP_ct_confirmed_enc_anon: return "confirmed_enc_anon";
    7.62 -    case PEP_ct_pEp: return "pEp";
    7.63 -    default: return "invalid comm type";
    7.64 -    }
    7.65 -}
    7.66 -
    7.67 -
    7.68  typedef enum _identity_flags {
    7.69      // the first octet flags are app defined settings
    7.70      PEP_idf_not_for_sync = 0x0001,   // don't use this identity for sync
     8.1 --- a/src/pgp_sequoia.c	Tue May 21 14:58:10 2019 +0200
     8.2 +++ b/src/pgp_sequoia.c	Wed May 29 16:43:38 2019 +0200
     8.3 @@ -803,8 +803,11 @@
     8.4                   
     8.5              }
     8.6              else {
     8.7 -                const char* split = strstr(uid_value, "<");
     8.8 -                if (split != uid_value) {       
     8.9 +                // Ok, asan gets really pissed at us using this string directly, SO...
    8.10 +                char* uid_copy = calloc(uid_value_len + 1, 1);
    8.11 +                strlcpy(uid_copy, uid_value, uid_value_len);
    8.12 +                const char* split = strstr(uid_copy, "<");
    8.13 +                if (split != uid_copy) {       
    8.14                      while (split) {
    8.15                          if (isspace(*(split - 1)))
    8.16                              break;
    8.17 @@ -831,9 +834,10 @@
    8.18                      else  
    8.19                          split = NULL;
    8.20                  }
    8.21 -                if (split == NULL) {
    8.22 -                    email = strdup(uid_value);
    8.23 -                }
    8.24 +                if (split == NULL)
    8.25 +                    email = uid_copy;
    8.26 +                else 
    8.27 +                    free(uid_copy);
    8.28              }
    8.29          }
    8.30          
    8.31 @@ -1643,6 +1647,11 @@
    8.32      if (write_status != 0)
    8.33          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
    8.34  
    8.35 +    pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    8.36 +    ws = NULL;
    8.37 +    if (pgp_status != 0)
    8.38 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    8.39 +
    8.40      // Add a terminating NUL for naive users
    8.41      void *t = realloc(*stext, *ssize + 1);
    8.42      if (! t)
    8.43 @@ -1651,13 +1660,6 @@
    8.44      (*stext)[*ssize] = 0;
    8.45  
    8.46   out:
    8.47 -    if (ws) {
    8.48 -        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    8.49 -        ws = NULL;
    8.50 -        if (pgp_status != 0)
    8.51 -            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    8.52 -    }
    8.53 -
    8.54      if (signer)
    8.55          pgp_signer_free (signer);
    8.56      if (signing_keypair)
    8.57 @@ -1763,21 +1765,22 @@
    8.58      if (write_status != 0)
    8.59          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
    8.60  
    8.61 +    pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    8.62 +    ws = NULL;
    8.63 +    if (pgp_status != 0)
    8.64 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    8.65 +
    8.66      // Add a terminating NUL for naive users
    8.67      void *t = realloc(*ctext, *csize + 1);
    8.68 -    if (! t)
    8.69 +    if (! t) {
    8.70 +        free(*ctext);
    8.71 +        *ctext = NULL;
    8.72          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    8.73 +    }
    8.74      *ctext = t;
    8.75      (*ctext)[*csize] = 0;
    8.76  
    8.77   out:
    8.78 -    if (ws) {
    8.79 -        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    8.80 -        ws = NULL;
    8.81 -        if (pgp_status != 0)
    8.82 -            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    8.83 -    }
    8.84 -
    8.85      if (signer)
    8.86          pgp_signer_free (signer);
    8.87      if (signing_keypair)
    8.88 @@ -2041,6 +2044,7 @@
    8.89      pgp_error_t err = NULL;
    8.90      pgp_tpk_t tpk = NULL;
    8.91      pgp_writer_t armor_writer = NULL;
    8.92 +    pgp_writer_t memory_writer = NULL;
    8.93  
    8.94      assert(session);
    8.95      assert(fpr);
    8.96 @@ -2057,13 +2061,12 @@
    8.97      status = tpk_find_by_fpr_hex(session, fpr, secret, &tpk, NULL);
    8.98      ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
    8.99  
   8.100 -    pgp_writer_t memory_writer = pgp_writer_alloc((void **) key_data, size);
   8.101 +    memory_writer = pgp_writer_alloc((void **) key_data, size);
   8.102      if (! memory_writer)
   8.103          ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
   8.104      armor_writer = pgp_armor_writer_new(&err, memory_writer,
   8.105                                          PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
   8.106      if (! armor_writer) {
   8.107 -        pgp_writer_free(memory_writer);
   8.108          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
   8.109      }
   8.110  
   8.111 @@ -2081,9 +2084,20 @@
   8.112      if (armor_writer)
   8.113          pgp_writer_free(armor_writer);
   8.114  
   8.115 +    if (memory_writer) {
   8.116 +        if (status == PEP_STATUS_OK) {
   8.117 +            // Add a trailing NUL.
   8.118 +            pgp_writer_write(NULL, memory_writer, (const uint8_t *) "", 1);
   8.119 +        }
   8.120 +
   8.121 +        pgp_writer_free(memory_writer);
   8.122 +    }
   8.123 +
   8.124      if (tpk)
   8.125          pgp_tpk_free(tpk);
   8.126  
   8.127 +    (*size)--;  // Sequoia is delivering the 0 byte at the end with size, but
   8.128 +                // pEp is expecting it without
   8.129      T("(%s) -> %s", fpr, pEp_status_to_string(status));
   8.130      return status;
   8.131  }
   8.132 @@ -2393,7 +2407,7 @@
   8.133      if (tpk)
   8.134          pgp_tpk_free(tpk);
   8.135  
   8.136 -    T("(%s) -> %s", fpr, pep_comm_type_to_string(*comm_type));
   8.137 +    T("(%s) -> %s", fpr, pEp_comm_type_to_string(*comm_type));
   8.138      return status;
   8.139  }
   8.140  
   8.141 @@ -2655,4 +2669,3 @@
   8.142        fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
   8.143      return status;
   8.144  }
   8.145 -
     9.1 --- a/src/status_to_string.h	Tue May 21 14:58:10 2019 +0200
     9.2 +++ b/src/status_to_string.h	Wed May 29 16:43:38 2019 +0200
     9.3 @@ -4,6 +4,10 @@
     9.4  extern "C" {
     9.5  #endif
     9.6  
     9.7 +#ifndef PEP_STATUS_TO_STRING
     9.8 +#define PEP_STATUS_TO_STRING
     9.9 +#endif
    9.10 +
    9.11  static inline const char *pEp_status_to_string(PEP_STATUS status) {
    9.12      switch (status) {
    9.13      case PEP_STATUS_OK: return "PEP_STATUS_OK";
    9.14 @@ -74,6 +78,7 @@
    9.15      case PEP_SYNC_NO_CHANNEL: return "PEP_SYNC_NO_CHANNEL";
    9.16      case PEP_SYNC_CANNOT_ENCRYPT: return "PEP_SYNC_CANNOT_ENCRYPT";
    9.17      case PEP_SYNC_NO_MESSAGE_SEND_CALLBACK: return "PEP_SYNC_NO_MESSAGE_SEND_CALLBACK";
    9.18 +    case PEP_SYNC_CANNOT_START: return "PEP_SYNC_CANNOT_START";
    9.19  
    9.20      case PEP_CANNOT_INCREASE_SEQUENCE: return "PEP_CANNOT_INCREASE_SEQUENCE";
    9.21  
    9.22 @@ -103,6 +108,46 @@
    9.23      }
    9.24  }
    9.25  
    9.26 +static inline const char *pEp_comm_type_to_string(PEP_comm_type ct) {
    9.27 +    switch (ct) {
    9.28 +    case PEP_ct_unknown: return "unknown";
    9.29 +    case PEP_ct_no_encryption: return "no_encryption";
    9.30 +    case PEP_ct_no_encrypted_channel: return "no_encrypted_channel";
    9.31 +    case PEP_ct_key_not_found: return "key_not_found";
    9.32 +    case PEP_ct_key_expired: return "key_expired";
    9.33 +    case PEP_ct_key_revoked: return "key_revoked";
    9.34 +    case PEP_ct_key_b0rken: return "key_b0rken";
    9.35 +    case PEP_ct_my_key_not_included: return "my_key_not_included";
    9.36 +    case PEP_ct_security_by_obscurity: return "security_by_obscurity";
    9.37 +    case PEP_ct_b0rken_crypto: return "b0rken_crypto";
    9.38 +    case PEP_ct_key_too_short: return "key_too_short";
    9.39 +    case PEP_ct_compromised: return "compromised";
    9.40 +    case PEP_ct_mistrusted: return "mistrusted";
    9.41 +    case PEP_ct_unconfirmed_encryption: return "unconfirmed_encryption";
    9.42 +    case PEP_ct_OpenPGP_weak_unconfirmed: return "OpenPGP_weak_unconfirmed";
    9.43 +    case PEP_ct_to_be_checked: return "to_be_checked";
    9.44 +    case PEP_ct_SMIME_unconfirmed: return "SMIME_unconfirmed";
    9.45 +    case PEP_ct_CMS_unconfirmed: return "CMS_unconfirmed";
    9.46 +    case PEP_ct_strong_but_unconfirmed: return "strong_but_unconfirmed";
    9.47 +    case PEP_ct_OpenPGP_unconfirmed: return "OpenPGP_unconfirmed";
    9.48 +    case PEP_ct_OTR_unconfirmed: return "OTR_unconfirmed";
    9.49 +    case PEP_ct_unconfirmed_enc_anon: return "unconfirmed_enc_anon";
    9.50 +    case PEP_ct_pEp_unconfirmed: return "pEp_unconfirmed";
    9.51 +    case PEP_ct_confirmed: return "confirmed";
    9.52 +    case PEP_ct_confirmed_encryption: return "confirmed_encryption";
    9.53 +    case PEP_ct_OpenPGP_weak: return "OpenPGP_weak";
    9.54 +    case PEP_ct_to_be_checked_confirmed: return "to_be_checked_confirmed";
    9.55 +    case PEP_ct_SMIME: return "SMIME";
    9.56 +    case PEP_ct_CMS: return "CMS";
    9.57 +    case PEP_ct_strong_encryption: return "strong_encryption";
    9.58 +    case PEP_ct_OpenPGP: return "OpenPGP";
    9.59 +    case PEP_ct_OTR: return "OTR";
    9.60 +    case PEP_ct_confirmed_enc_anon: return "confirmed_enc_anon";
    9.61 +    case PEP_ct_pEp: return "pEp";
    9.62 +    default: return "invalid comm type";
    9.63 +    }
    9.64 +}
    9.65 +
    9.66  #ifdef __cplusplus
    9.67  } // "C"
    9.68  #endif
    10.1 --- a/src/sync_api.c	Tue May 21 14:58:10 2019 +0200
    10.2 +++ b/src/sync_api.c	Wed May 29 16:43:38 2019 +0200
    10.3 @@ -19,6 +19,15 @@
    10.4      if (!(session && notifyHandshake && retrieve_next_sync_event))
    10.5          return PEP_ILLEGAL_VALUE;
    10.6  
    10.7 +    identity_list *own_identities = NULL;
    10.8 +    PEP_STATUS status = own_identities_retrieve(session, &own_identities);
    10.9 +    if (status)
   10.10 +        return status;
   10.11 +    bool own_identities_available = own_identities && own_identities->ident;
   10.12 +    free_identity_list(own_identities);
   10.13 +    if (!own_identities_available)
   10.14 +        return PEP_SYNC_CANNOT_START;
   10.15 +
   10.16      session->sync_management = management;
   10.17      session->notifyHandshake = notifyHandshake;
   10.18      session->retrieve_next_sync_event = retrieve_next_sync_event;
    11.1 --- a/sync/cond_act_sync.yml2	Tue May 21 14:58:10 2019 +0200
    11.2 +++ b/sync/cond_act_sync.yml2	Wed May 29 16:43:38 2019 +0200
    11.3 @@ -416,18 +416,25 @@
    11.4      if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
    11.5          return PEP_ILLEGAL_VALUE;
    11.6  
    11.7 -    pEp_identity *ident = session->sync_state.common.from;
    11.8 +    pEp_identity *ident = identity_dup(session->sync_state.common.from);
    11.9 +    if (!ident)
   11.10 +        return PEP_OUT_OF_MEMORY;
   11.11      free(ident->fpr);
   11.12      ident->fpr = strdup(session->sync_state.common.signature_fpr);
   11.13      assert(ident->fpr);
   11.14 -    if (!ident->fpr)
   11.15 +    if (!ident->fpr) {
   11.16 +        free_identity(ident);
   11.17          return PEP_OUT_OF_MEMORY;
   11.18 +    }
   11.19  
   11.20      PEP_STATUS status = trust_own_key(session, ident);
   11.21 -    if (status)
   11.22 +    if (status) {
   11.23 +        free_identity(ident);
   11.24          return status;
   11.25 +    }
   11.26  
   11.27      OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
   11.28 +    free_identity(ident);
   11.29  ||
   11.30  
   11.31  action untrustThisKey
    12.1 --- a/sync/gen_statemachine.ysl2	Tue May 21 14:58:10 2019 +0200
    12.2 +++ b/sync/gen_statemachine.ysl2	Wed May 29 16:43:38 2019 +0200
    12.3 @@ -766,6 +766,8 @@
    12.4                  free(data);
    12.5                  free(key_data);
    12.6                  free_«@name»_message(msg);
    12.7 +                if (status)
    12.8 +                    SERVICE_ERROR_LOG(session, "send_«@name»_message()", status);
    12.9                  return status;
   12.10              }
   12.11  
    13.1 --- a/test/src/engine_tests/URIAddressTests.cc	Tue May 21 14:58:10 2019 +0200
    13.2 +++ b/test/src/engine_tests/URIAddressTests.cc	Wed May 29 16:43:38 2019 +0200
    13.3 @@ -40,7 +40,9 @@
    13.4      status = export_key(session, me->fpr, 
    13.5                          &keydata, &keysize);
    13.6  
    13.7 -    cout << keydata << endl;
    13.8 +    TEST_ASSERT(keydata && keysize > 0);
    13.9 +    // no guarantee of NUL-termination atm.
   13.10 +//    cout << keydata << endl;
   13.11  
   13.12      free(keydata);
   13.13      free_identity(me);