ENGINE-524: merge in sync ENGINE-524
authorClaudio Luck <claudio.luck@pep.foundation>
Thu, 30 May 2019 02:16:49 +0200
branchENGINE-524
changeset 3839f264464b1cfa
parent 3838 c2941a9d7f2b
parent 3783 119aba513e36
child 3840 bfef390b48e2
ENGINE-524: merge in sync
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/pgp_sequoia.c
     1.1 --- a/src/message_api.c	Thu May 30 02:16:16 2019 +0200
     1.2 +++ b/src/message_api.c	Thu May 30 02:16:49 2019 +0200
     1.3 @@ -1572,7 +1572,7 @@
     1.4  PEP_STATUS _attach_key(PEP_SESSION session, const char* fpr, message *msg)
     1.5  {
     1.6      char *keydata = NULL;
     1.7 -    size_t size;
     1.8 +    size_t size = 0;
     1.9  
    1.10      PEP_STATUS status = export_key(session, fpr, &keydata, &size);
    1.11      assert(status == PEP_STATUS_OK);
    1.12 @@ -1580,7 +1580,7 @@
    1.13          return status;
    1.14      assert(size);
    1.15  
    1.16 -     bloblist_t *bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
    1.17 +    bloblist_t *bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
    1.18                        "file://pEpkey.asc");
    1.19  
    1.20      if (msg->attachments == NULL && bl)
    1.21 @@ -3893,15 +3893,16 @@
    1.22              !(*flags & PEP_decrypt_flag_dont_trigger_sync)) {
    1.23          size_t size;
    1.24          const char *data;
    1.25 -        char *sync_fpr = NULL;
    1.26 -        PEP_STATUS tmpstatus = base_extract_message(session, msg, &size, &data, &sync_fpr);
    1.27 +        char *sender_fpr = NULL;
    1.28 +        PEP_STATUS tmpstatus = base_extract_message(session, msg, &size, &data, &sender_fpr);
    1.29          if (!tmpstatus && size && data) {
    1.30 -            if (sync_fpr)
    1.31 -                signal_Sync_message(session, *rating, data, size, msg->from, sync_fpr);
    1.32 +            if (sender_fpr)
    1.33 +                signal_Sync_message(session, *rating, data, size, msg->from, sender_fpr);
    1.34 +            // FIXME: this must be changed to sender_fpr
    1.35              else if (*keylist)
    1.36                  signal_Sync_message(session, *rating, data, size, msg->from, (*keylist)->value);
    1.37          }
    1.38 -        free(sync_fpr);
    1.39 +        free(sender_fpr);
    1.40      }
    1.41  
    1.42      return status;
    1.43 @@ -4207,7 +4208,7 @@
    1.44      return num_to_asciihex(xor_num);
    1.45  }
    1.46  
    1.47 -static char* skip_separators(char* current, char* begin) {
    1.48 +static const char* skip_separators(const char* current, const char* begin) {
    1.49      while (current >= begin) {
    1.50          /* .:,;-_ ' ' - [2c-2e] [3a-3b] [20] [5f] */
    1.51          char check_char = *current;
    1.52 @@ -4245,71 +4246,73 @@
    1.53  }
    1.54  
    1.55  DYNAMIC_API PEP_STATUS get_trustwords(
    1.56 -    PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    1.57 -    const char* lang, char **words, size_t *wsize, bool full
    1.58 -)
    1.59 +        PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    1.60 +        const char* lang, char **words, size_t *wsize, bool full
    1.61 +    )
    1.62  {
    1.63 -    assert(session);
    1.64 -    assert(id1);
    1.65 -    assert(id2);
    1.66 -    assert(id1->fpr);
    1.67 -    assert(id2->fpr);
    1.68 -    assert(words);
    1.69 -    assert(wsize);
    1.70 -
    1.71 -    int SHORT_NUM_TWORDS = 5; 
    1.72 -    
    1.73 +    assert(session && id1 && id1->fpr && id2 && id2->fpr&& lang && words &&
    1.74 +            wsize);
    1.75 +    if (!(session && id1 && id1->fpr && id2 && id2->fpr&& lang && words &&
    1.76 +                wsize))
    1.77 +        return PEP_ILLEGAL_VALUE;
    1.78 +
    1.79 +    return get_trustwords_for_fprs(session, id1->fpr, id2->fpr, lang, words,
    1.80 +            wsize, full);
    1.81 +}
    1.82 +
    1.83 +DYNAMIC_API PEP_STATUS get_trustwords_for_fprs(
    1.84 +        PEP_SESSION session, const char* fpr1, const char* fpr2,
    1.85 +        const char* lang, char **words, size_t *wsize, bool full
    1.86 +    )
    1.87 +{
    1.88 +    assert(session && fpr1 && fpr2 && words && wsize);
    1.89 +    if (!(session && fpr1 && fpr2 && words && wsize))
    1.90 +        return PEP_ILLEGAL_VALUE;
    1.91 +
    1.92 +    const int SHORT_NUM_TWORDS = 5; 
    1.93      PEP_STATUS status = PEP_STATUS_OK;
    1.94      
    1.95 -    if (!(session && id1 && id2 && words && wsize) ||
    1.96 -        !(id1->fpr) || (!id2->fpr))
    1.97 -        return PEP_ILLEGAL_VALUE;
    1.98 -
    1.99 -    char *source1 = id1->fpr;
   1.100 -    char *source2 = id2->fpr;
   1.101 -
   1.102 -    int source1_len = strlen(source1);
   1.103 -    int source2_len = strlen(source2);
   1.104 -    int max_len;
   1.105 -        
   1.106      *words = NULL;    
   1.107      *wsize = 0;
   1.108  
   1.109 -    max_len = (source1_len > source2_len ? source1_len : source2_len);
   1.110 +    int fpr1_len = strlen(fpr1);
   1.111 +    int fpr2_len = strlen(fpr2);
   1.112 +        
   1.113 +    int max_len = (fpr1_len > fpr2_len ? fpr1_len : fpr2_len);
   1.114      
   1.115      char* XORed_fpr = (char*)(calloc(max_len + 1, 1));
   1.116      *(XORed_fpr + max_len) = '\0';
   1.117      char* result_curr = XORed_fpr + max_len - 1;
   1.118 -    char* source1_curr = source1 + source1_len - 1;
   1.119 -    char* source2_curr = source2 + source2_len - 1;
   1.120 -
   1.121 -    while (source1 <= source1_curr && source2 <= source2_curr) {
   1.122 -        source1_curr = skip_separators(source1_curr, source1);
   1.123 -        source2_curr = skip_separators(source2_curr, source2);
   1.124 +    const char* fpr1_curr = fpr1 + fpr1_len - 1;
   1.125 +    const char* fpr2_curr = fpr2 + fpr2_len - 1;
   1.126 +
   1.127 +    while (fpr1 <= fpr1_curr && fpr2 <= fpr2_curr) {
   1.128 +        fpr1_curr = skip_separators(fpr1_curr, fpr1);
   1.129 +        fpr2_curr = skip_separators(fpr2_curr, fpr2);
   1.130          
   1.131 -        if (source1_curr < source1 || source2_curr < source2)
   1.132 +        if (fpr1_curr < fpr1 || fpr2_curr < fpr2)
   1.133              break;
   1.134              
   1.135 -        char xor_hex = xor_hex_chars(*source1_curr, *source2_curr);
   1.136 +        char xor_hex = xor_hex_chars(*fpr1_curr, *fpr2_curr);
   1.137          if (xor_hex == '\0') {
   1.138              status = PEP_ILLEGAL_VALUE;
   1.139              goto error_release;
   1.140          }
   1.141          
   1.142          *result_curr = xor_hex;
   1.143 -        result_curr--; source1_curr--; source2_curr--;
   1.144 +        result_curr--; fpr1_curr--; fpr2_curr--;
   1.145      }
   1.146  
   1.147 -    char* remainder_start = NULL;
   1.148 -    char* remainder_curr = NULL;
   1.149 +    const char* remainder_start = NULL;
   1.150 +    const char* remainder_curr = NULL;
   1.151      
   1.152 -    if (source1 <= source1_curr) {
   1.153 -        remainder_start = source1;
   1.154 -        remainder_curr = source1_curr;
   1.155 +    if (fpr1 <= fpr1_curr) {
   1.156 +        remainder_start = fpr1;
   1.157 +        remainder_curr = fpr1_curr;
   1.158      }
   1.159 -    else if (source2 <= source2_curr) {
   1.160 -        remainder_start = source2;
   1.161 -        remainder_curr = source2_curr;
   1.162 +    else if (fpr2 <= fpr2_curr) {
   1.163 +        remainder_start = fpr2;
   1.164 +        remainder_curr = fpr2_curr;
   1.165      }
   1.166      if (remainder_curr) {
   1.167          while (remainder_start <= remainder_curr) {
     2.1 --- a/src/message_api.h	Thu May 30 02:16:16 2019 +0200
     2.2 +++ b/src/message_api.h	Thu May 30 02:16:49 2019 +0200
     2.3 @@ -388,9 +388,9 @@
     2.4  //        the caller is responsible to free() it (on Windoze use pEp_free())
     2.5  //
     2.6  DYNAMIC_API PEP_STATUS get_trustwords(
     2.7 -    PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
     2.8 -    const char* lang, char **words, size_t *wsize, bool full
     2.9 -);
    2.10 +        PEP_SESSION session, const pEp_identity* id1, const pEp_identity* id2,
    2.11 +        const char* lang, char **words, size_t *wsize, bool full
    2.12 +    );
    2.13  
    2.14  
    2.15  // get_message_trustwords() - get full trustwords string for message sender and reciever identities 
    2.16 @@ -421,12 +421,42 @@
    2.17  //        the caller is responsible to free() it (on Windoze use pEp_free())
    2.18  //
    2.19  DYNAMIC_API PEP_STATUS get_message_trustwords(
    2.20 -    PEP_SESSION session, 
    2.21 -    message *msg,
    2.22 -    stringlist_t *keylist,
    2.23 -    pEp_identity* received_by,
    2.24 -    const char* lang, char **words, bool full
    2.25 -);
    2.26 +        PEP_SESSION session, 
    2.27 +        message *msg,
    2.28 +        stringlist_t *keylist,
    2.29 +        pEp_identity* received_by,
    2.30 +        const char* lang, char **words, bool full
    2.31 +    );
    2.32 +
    2.33 +// get_trustwords_for_fprs() - get full trustwords string for a pair of fingerprints
    2.34 +//
    2.35 +//    parameters:
    2.36 +//        session (in)        session handle
    2.37 +//        fpr1 (in)           fingerprint 1
    2.38 +//        fpr2 (in)           fingerprint 2
    2.39 +//        lang (in)           C string with ISO 639-1 language code
    2.40 +//        words (out)         pointer to C string with all trustwords UTF-8 encoded,
    2.41 +//                            separated by a blank each
    2.42 +//                            NULL if language is not supported or trustword
    2.43 +//                            wordlist is damaged or unavailable
    2.44 +//        wsize (out)         length of full trustwords string
    2.45 +//        full (in)           if true, generate ALL trustwords for these identities.
    2.46 +//                            else, generate a fixed-size subset. (TODO: fixed-minimum-entropy
    2.47 +//                            subset in next version)
    2.48 +//
    2.49 +//    return value:
    2.50 +//        PEP_STATUS_OK            trustwords retrieved
    2.51 +//        PEP_OUT_OF_MEMORY        out of memory
    2.52 +//        PEP_TRUSTWORD_NOT_FOUND  at least one trustword not found
    2.53 +//
    2.54 +//    caveat:
    2.55 +//        the word pointer goes to the ownership of the caller
    2.56 +//        the caller is responsible to free() it (on Windoze use pEp_free())
    2.57 +//
    2.58 +DYNAMIC_API PEP_STATUS get_trustwords_for_fprs(
    2.59 +        PEP_SESSION session, const char* fpr1, const char* fpr2,
    2.60 +        const char* lang, char **words, size_t *wsize, bool full
    2.61 +    );
    2.62  
    2.63  // re_evaluate_message_rating() - re-evaluate already decrypted message rating
    2.64  //
     3.1 --- a/src/pEpEngine.c	Thu May 30 02:16:16 2019 +0200
     3.2 +++ b/src/pEpEngine.c	Thu May 30 02:16:49 2019 +0200
     3.3 @@ -2039,32 +2039,31 @@
     3.4  #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
     3.5      fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
     3.6      session->service_log = true;
     3.7 +
     3.8 +    int result;
     3.9 +    
    3.10 +    assert(session);
    3.11 +    assert(title);
    3.12 +    assert(entity);
    3.13 +    
    3.14 +    if (!(session && title && entity))
    3.15 +        return PEP_ILLEGAL_VALUE;
    3.16 +    
    3.17 +    sqlite3_reset(session->log);
    3.18 +    sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
    3.19 +    sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
    3.20 +    if (description)
    3.21 +        sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
    3.22 +    else
    3.23 +        sqlite3_bind_null(session->log, 3);
    3.24 +    if (comment)
    3.25 +        sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
    3.26 +    else
    3.27 +        sqlite3_bind_null(session->log, 4);
    3.28 +    result = Sqlite3_step(session->log);
    3.29 +    sqlite3_reset(session->log);
    3.30 +    
    3.31  #endif
    3.32 -
    3.33 -    // PEP_STATUS status = PEP_STATUS_OK;
    3.34 -    // int result;
    3.35 -    // 
    3.36 -    // assert(session);
    3.37 -    // assert(title);
    3.38 -    // assert(entity);
    3.39 -    // 
    3.40 -    // if (!(session && title && entity))
    3.41 -    //     return PEP_ILLEGAL_VALUE;
    3.42 -    // 
    3.43 -    // sqlite3_reset(session->log);
    3.44 -    // sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
    3.45 -    // sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
    3.46 -    // if (description)
    3.47 -    //     sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
    3.48 -    // else
    3.49 -    //     sqlite3_bind_null(session->log, 3);
    3.50 -    // if (comment)
    3.51 -    //     sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
    3.52 -    // else
    3.53 -    //     sqlite3_bind_null(session->log, 4);
    3.54 -    // result = Sqlite3_step(session->log);
    3.55 -    // sqlite3_reset(session->log);
    3.56 -    // 
    3.57      return PEP_STATUS_OK; // We ignore errors for this function.
    3.58  }
    3.59  
    3.60 @@ -2426,7 +2425,7 @@
    3.61      )
    3.62  {
    3.63      PEP_STATUS status = PEP_STATUS_OK;
    3.64 -    static pEp_identity *_identity;
    3.65 +    pEp_identity *_identity = NULL;
    3.66  
    3.67      assert(session);
    3.68      assert(address);
    3.69 @@ -2637,7 +2636,7 @@
    3.70      )
    3.71  {
    3.72      PEP_STATUS status = PEP_STATUS_OK;
    3.73 -    static pEp_identity *_identity;
    3.74 +    pEp_identity *_identity = NULL;
    3.75  
    3.76      assert(session);
    3.77      assert(address);
    3.78 @@ -5093,3 +5092,17 @@
    3.79  }
    3.80  
    3.81  #endif
    3.82 +
    3.83 +DYNAMIC_API void _service_error_log(PEP_SESSION session, const char *entity,
    3.84 +        PEP_STATUS status, const char *where)
    3.85 +{
    3.86 +    char buffer[128];
    3.87 +    static const size_t size = 127;
    3.88 +    memset(buffer, 0, size+1);
    3.89 +#ifdef PEP_STATUS_TO_STRING
    3.90 +    snprintf(buffer, size, "%s %.4x", pEp_status_to_string(status), status);
    3.91 +#else
    3.92 +    snprintf(buffer, size, "error %.4x", status);
    3.93 +#endif
    3.94 +    log_service(session, "### service error log ###", entity, buffer, where);
    3.95 +}
     4.1 --- a/src/pEpEngine.h	Thu May 30 02:16:16 2019 +0200
     4.2 +++ b/src/pEpEngine.h	Thu May 30 02:16:49 2019 +0200
     4.3 @@ -103,6 +103,7 @@
     4.4      PEP_SYNC_NO_CHANNEL                             = 0x0904,
     4.5      PEP_SYNC_CANNOT_ENCRYPT                         = 0x0905,
     4.6      PEP_SYNC_NO_MESSAGE_SEND_CALLBACK               = 0x0906,
     4.7 +    PEP_SYNC_CANNOT_START                           = 0x0907,
     4.8  
     4.9      PEP_CANNOT_INCREASE_SEQUENCE                    = 0x0971,
    4.10  
    4.11 @@ -468,6 +469,11 @@
    4.12  #define SERVICE_LOG(session, title, entity, desc) \
    4.13      log_service((session), (title), (entity), (desc), "service " __FILE__ ":" S_LINE)
    4.14  
    4.15 +DYNAMIC_API void _service_error_log(PEP_SESSION session, const char *entity,
    4.16 +        PEP_STATUS status, const char *where);
    4.17 +
    4.18 +#define SERVICE_ERROR_LOG(session, entity, status) \
    4.19 +    _service_error_log((session), (entity), (status), __FILE__ ":" S_LINE)
    4.20  
    4.21  // trustword() - get the corresponding trustword for a 16 bit value
    4.22  //
    4.23 @@ -593,47 +599,6 @@
    4.24      PEP_ct_pEp = 0xff
    4.25  } PEP_comm_type;
    4.26  
    4.27 -static inline const char *pep_comm_type_to_string(PEP_comm_type ct) {
    4.28 -    switch (ct) {
    4.29 -    case PEP_ct_unknown: return "unknown";
    4.30 -    case PEP_ct_no_encryption: return "no_encryption";
    4.31 -    case PEP_ct_no_encrypted_channel: return "no_encrypted_channel";
    4.32 -    case PEP_ct_key_not_found: return "key_not_found";
    4.33 -    case PEP_ct_key_expired: return "key_expired";
    4.34 -    case PEP_ct_key_revoked: return "key_revoked";
    4.35 -    case PEP_ct_key_b0rken: return "key_b0rken";
    4.36 -    case PEP_ct_my_key_not_included: return "my_key_not_included";
    4.37 -    case PEP_ct_security_by_obscurity: return "security_by_obscurity";
    4.38 -    case PEP_ct_b0rken_crypto: return "b0rken_crypto";
    4.39 -    case PEP_ct_key_too_short: return "key_too_short";
    4.40 -    case PEP_ct_compromised: return "compromised";
    4.41 -    case PEP_ct_mistrusted: return "mistrusted";
    4.42 -    case PEP_ct_unconfirmed_encryption: return "unconfirmed_encryption";
    4.43 -    case PEP_ct_OpenPGP_weak_unconfirmed: return "OpenPGP_weak_unconfirmed";
    4.44 -    case PEP_ct_to_be_checked: return "to_be_checked";
    4.45 -    case PEP_ct_SMIME_unconfirmed: return "SMIME_unconfirmed";
    4.46 -    case PEP_ct_CMS_unconfirmed: return "CMS_unconfirmed";
    4.47 -    case PEP_ct_strong_but_unconfirmed: return "strong_but_unconfirmed";
    4.48 -    case PEP_ct_OpenPGP_unconfirmed: return "OpenPGP_unconfirmed";
    4.49 -    case PEP_ct_OTR_unconfirmed: return "OTR_unconfirmed";
    4.50 -    case PEP_ct_unconfirmed_enc_anon: return "unconfirmed_enc_anon";
    4.51 -    case PEP_ct_pEp_unconfirmed: return "pEp_unconfirmed";
    4.52 -    case PEP_ct_confirmed: return "confirmed";
    4.53 -    case PEP_ct_confirmed_encryption: return "confirmed_encryption";
    4.54 -    case PEP_ct_OpenPGP_weak: return "OpenPGP_weak";
    4.55 -    case PEP_ct_to_be_checked_confirmed: return "to_be_checked_confirmed";
    4.56 -    case PEP_ct_SMIME: return "SMIME";
    4.57 -    case PEP_ct_CMS: return "CMS";
    4.58 -    case PEP_ct_strong_encryption: return "strong_encryption";
    4.59 -    case PEP_ct_OpenPGP: return "OpenPGP";
    4.60 -    case PEP_ct_OTR: return "OTR";
    4.61 -    case PEP_ct_confirmed_enc_anon: return "confirmed_enc_anon";
    4.62 -    case PEP_ct_pEp: return "pEp";
    4.63 -    default: return "invalid comm type";
    4.64 -    }
    4.65 -}
    4.66 -
    4.67 -
    4.68  typedef enum _identity_flags {
    4.69      // the first octet flags are app defined settings
    4.70      PEP_idf_not_for_sync = 0x0001,   // don't use this identity for sync
     5.1 --- a/src/pEp_internal.h	Thu May 30 02:16:16 2019 +0200
     5.2 +++ b/src/pEp_internal.h	Thu May 30 02:16:49 2019 +0200
     5.3 @@ -255,7 +255,6 @@
     5.4      void *sync_management;
     5.5      void *sync_obj;
     5.6      struct Sync_state_s sync_state;
     5.7 -    struct own_Sync_state_s own_sync_state;
     5.8  
     5.9  //     void* sync_state_payload;
    5.10  //     char sync_uuid[37];
     6.1 --- a/src/pgp_sequoia.c	Thu May 30 02:16:16 2019 +0200
     6.2 +++ b/src/pgp_sequoia.c	Thu May 30 02:16:49 2019 +0200
     6.3 @@ -791,8 +791,11 @@
     6.4                   
     6.5              }
     6.6              else {
     6.7 -                const char* split = strstr(uid_value, "<");
     6.8 -                if (split != uid_value) {       
     6.9 +                // Ok, asan gets really pissed at us using this string directly, SO...
    6.10 +                char* uid_copy = calloc(uid_value_len + 1, 1);
    6.11 +                strlcpy(uid_copy, uid_value, uid_value_len);
    6.12 +                const char* split = strstr(uid_copy, "<");
    6.13 +                if (split != uid_copy) {       
    6.14                      while (split) {
    6.15                          if (isspace(*(split - 1)))
    6.16                              break;
    6.17 @@ -819,9 +822,10 @@
    6.18                      else  
    6.19                          split = NULL;
    6.20                  }
    6.21 -                if (split == NULL) {
    6.22 -                    email = strdup(uid_value);
    6.23 -                }
    6.24 +                if (split == NULL)
    6.25 +                    email = uid_copy;
    6.26 +                else 
    6.27 +                    free(uid_copy);
    6.28              }
    6.29          }
    6.30          
    6.31 @@ -1631,6 +1635,11 @@
    6.32      if (write_status != 0)
    6.33          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
    6.34  
    6.35 +    pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    6.36 +    ws = NULL;
    6.37 +    if (pgp_status != 0)
    6.38 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    6.39 +
    6.40      // Add a terminating NUL for naive users
    6.41      void *t = realloc(*stext, *ssize + 1);
    6.42      if (! t)
    6.43 @@ -1639,13 +1648,6 @@
    6.44      (*stext)[*ssize] = 0;
    6.45  
    6.46   out:
    6.47 -    if (ws) {
    6.48 -        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    6.49 -        ws = NULL;
    6.50 -        if (pgp_status != 0)
    6.51 -            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    6.52 -    }
    6.53 -
    6.54      if (signer)
    6.55          pgp_signer_free (signer);
    6.56      if (signing_keypair)
    6.57 @@ -1751,21 +1753,22 @@
    6.58      if (write_status != 0)
    6.59          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
    6.60  
    6.61 +    pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    6.62 +    ws = NULL;
    6.63 +    if (pgp_status != 0)
    6.64 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    6.65 +
    6.66      // Add a terminating NUL for naive users
    6.67      void *t = realloc(*ctext, *csize + 1);
    6.68 -    if (! t)
    6.69 +    if (! t) {
    6.70 +        free(*ctext);
    6.71 +        *ctext = NULL;
    6.72          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    6.73 +    }
    6.74      *ctext = t;
    6.75      (*ctext)[*csize] = 0;
    6.76  
    6.77   out:
    6.78 -    if (ws) {
    6.79 -        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
    6.80 -        ws = NULL;
    6.81 -        if (pgp_status != 0)
    6.82 -            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
    6.83 -    }
    6.84 -
    6.85      if (signer)
    6.86          pgp_signer_free (signer);
    6.87      if (signing_keypair)
    6.88 @@ -2029,6 +2032,7 @@
    6.89      pgp_error_t err = NULL;
    6.90      pgp_tpk_t tpk = NULL;
    6.91      pgp_writer_t armor_writer = NULL;
    6.92 +    pgp_writer_t memory_writer = NULL;
    6.93  
    6.94      assert(session);
    6.95      assert(fpr);
    6.96 @@ -2045,13 +2049,12 @@
    6.97      status = tpk_find_by_fpr_hex(session, fpr, secret, &tpk, NULL);
    6.98      ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
    6.99  
   6.100 -    pgp_writer_t memory_writer = pgp_writer_alloc((void **) key_data, size);
   6.101 +    memory_writer = pgp_writer_alloc((void **) key_data, size);
   6.102      if (! memory_writer)
   6.103          ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
   6.104      armor_writer = pgp_armor_writer_new(&err, memory_writer,
   6.105                                          PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
   6.106      if (! armor_writer) {
   6.107 -        pgp_writer_free(memory_writer);
   6.108          ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
   6.109      }
   6.110  
   6.111 @@ -2069,9 +2072,20 @@
   6.112      if (armor_writer)
   6.113          pgp_writer_free(armor_writer);
   6.114  
   6.115 +    if (memory_writer) {
   6.116 +        if (status == PEP_STATUS_OK) {
   6.117 +            // Add a trailing NUL.
   6.118 +            pgp_writer_write(NULL, memory_writer, (const uint8_t *) "", 1);
   6.119 +        }
   6.120 +
   6.121 +        pgp_writer_free(memory_writer);
   6.122 +    }
   6.123 +
   6.124      if (tpk)
   6.125          pgp_tpk_free(tpk);
   6.126  
   6.127 +    (*size)--;  // Sequoia is delivering the 0 byte at the end with size, but
   6.128 +                // pEp is expecting it without
   6.129      T("(%s) -> %s", fpr, pEp_status_to_string(status));
   6.130      return status;
   6.131  }
   6.132 @@ -2381,7 +2395,7 @@
   6.133      if (tpk)
   6.134          pgp_tpk_free(tpk);
   6.135  
   6.136 -    T("(%s) -> %s", fpr, pep_comm_type_to_string(*comm_type));
   6.137 +    T("(%s) -> %s", fpr, pEp_comm_type_to_string(*comm_type));
   6.138      return status;
   6.139  }
   6.140  
   6.141 @@ -2643,4 +2657,3 @@
   6.142        fpr, *has_private ? "priv" : "pub", pEp_status_to_string(status));
   6.143      return status;
   6.144  }
   6.145 -
     7.1 --- a/src/status_to_string.h	Thu May 30 02:16:16 2019 +0200
     7.2 +++ b/src/status_to_string.h	Thu May 30 02:16:49 2019 +0200
     7.3 @@ -4,6 +4,10 @@
     7.4  extern "C" {
     7.5  #endif
     7.6  
     7.7 +#ifndef PEP_STATUS_TO_STRING
     7.8 +#define PEP_STATUS_TO_STRING
     7.9 +#endif
    7.10 +
    7.11  static inline const char *pEp_status_to_string(PEP_STATUS status) {
    7.12      switch (status) {
    7.13      case PEP_STATUS_OK: return "PEP_STATUS_OK";
    7.14 @@ -74,6 +78,7 @@
    7.15      case PEP_SYNC_NO_CHANNEL: return "PEP_SYNC_NO_CHANNEL";
    7.16      case PEP_SYNC_CANNOT_ENCRYPT: return "PEP_SYNC_CANNOT_ENCRYPT";
    7.17      case PEP_SYNC_NO_MESSAGE_SEND_CALLBACK: return "PEP_SYNC_NO_MESSAGE_SEND_CALLBACK";
    7.18 +    case PEP_SYNC_CANNOT_START: return "PEP_SYNC_CANNOT_START";
    7.19  
    7.20      case PEP_CANNOT_INCREASE_SEQUENCE: return "PEP_CANNOT_INCREASE_SEQUENCE";
    7.21  
    7.22 @@ -103,6 +108,46 @@
    7.23      }
    7.24  }
    7.25  
    7.26 +static inline const char *pEp_comm_type_to_string(PEP_comm_type ct) {
    7.27 +    switch (ct) {
    7.28 +    case PEP_ct_unknown: return "unknown";
    7.29 +    case PEP_ct_no_encryption: return "no_encryption";
    7.30 +    case PEP_ct_no_encrypted_channel: return "no_encrypted_channel";
    7.31 +    case PEP_ct_key_not_found: return "key_not_found";
    7.32 +    case PEP_ct_key_expired: return "key_expired";
    7.33 +    case PEP_ct_key_revoked: return "key_revoked";
    7.34 +    case PEP_ct_key_b0rken: return "key_b0rken";
    7.35 +    case PEP_ct_my_key_not_included: return "my_key_not_included";
    7.36 +    case PEP_ct_security_by_obscurity: return "security_by_obscurity";
    7.37 +    case PEP_ct_b0rken_crypto: return "b0rken_crypto";
    7.38 +    case PEP_ct_key_too_short: return "key_too_short";
    7.39 +    case PEP_ct_compromised: return "compromised";
    7.40 +    case PEP_ct_mistrusted: return "mistrusted";
    7.41 +    case PEP_ct_unconfirmed_encryption: return "unconfirmed_encryption";
    7.42 +    case PEP_ct_OpenPGP_weak_unconfirmed: return "OpenPGP_weak_unconfirmed";
    7.43 +    case PEP_ct_to_be_checked: return "to_be_checked";
    7.44 +    case PEP_ct_SMIME_unconfirmed: return "SMIME_unconfirmed";
    7.45 +    case PEP_ct_CMS_unconfirmed: return "CMS_unconfirmed";
    7.46 +    case PEP_ct_strong_but_unconfirmed: return "strong_but_unconfirmed";
    7.47 +    case PEP_ct_OpenPGP_unconfirmed: return "OpenPGP_unconfirmed";
    7.48 +    case PEP_ct_OTR_unconfirmed: return "OTR_unconfirmed";
    7.49 +    case PEP_ct_unconfirmed_enc_anon: return "unconfirmed_enc_anon";
    7.50 +    case PEP_ct_pEp_unconfirmed: return "pEp_unconfirmed";
    7.51 +    case PEP_ct_confirmed: return "confirmed";
    7.52 +    case PEP_ct_confirmed_encryption: return "confirmed_encryption";
    7.53 +    case PEP_ct_OpenPGP_weak: return "OpenPGP_weak";
    7.54 +    case PEP_ct_to_be_checked_confirmed: return "to_be_checked_confirmed";
    7.55 +    case PEP_ct_SMIME: return "SMIME";
    7.56 +    case PEP_ct_CMS: return "CMS";
    7.57 +    case PEP_ct_strong_encryption: return "strong_encryption";
    7.58 +    case PEP_ct_OpenPGP: return "OpenPGP";
    7.59 +    case PEP_ct_OTR: return "OTR";
    7.60 +    case PEP_ct_confirmed_enc_anon: return "confirmed_enc_anon";
    7.61 +    case PEP_ct_pEp: return "pEp";
    7.62 +    default: return "invalid comm type";
    7.63 +    }
    7.64 +}
    7.65 +
    7.66  #ifdef __cplusplus
    7.67  } // "C"
    7.68  #endif
     8.1 --- a/src/sync_api.c	Thu May 30 02:16:16 2019 +0200
     8.2 +++ b/src/sync_api.c	Thu May 30 02:16:49 2019 +0200
     8.3 @@ -19,6 +19,15 @@
     8.4      if (!(session && notifyHandshake && retrieve_next_sync_event))
     8.5          return PEP_ILLEGAL_VALUE;
     8.6  
     8.7 +    identity_list *own_identities = NULL;
     8.8 +    PEP_STATUS status = own_identities_retrieve(session, &own_identities);
     8.9 +    if (status)
    8.10 +        return status;
    8.11 +    bool own_identities_available = own_identities && own_identities->ident;
    8.12 +    free_identity_list(own_identities);
    8.13 +    if (!own_identities_available)
    8.14 +        return PEP_SYNC_CANNOT_START;
    8.15 +
    8.16      session->sync_management = management;
    8.17      session->notifyHandshake = notifyHandshake;
    8.18      session->retrieve_next_sync_event = retrieve_next_sync_event;
     9.1 --- a/sync/cond_act_sync.yml2	Thu May 30 02:16:16 2019 +0200
     9.2 +++ b/sync/cond_act_sync.yml2	Thu May 30 02:16:49 2019 +0200
     9.3 @@ -21,7 +21,7 @@
     9.4  condition weAreFirst
     9.5  ||
     9.6      TID_t *t1 = &session->sync_state.keysync.challenge;
     9.7 -    TID_t *t2 = &session->own_sync_state.challenge;
     9.8 +    TID_t *t2 = &session->sync_state.own.challenge;
     9.9  
    9.10      *result = _TID_greater(t1, t2);
    9.11  ||
    9.12 @@ -29,38 +29,30 @@
    9.13  condition partnerIsGrouped
    9.14  |> *result = session->sync_state.keysync.is_group;
    9.15  
    9.16 -condition challengeAccepted
    9.17 +condition sameChallenge
    9.18  ||
    9.19      TID_t *t1 = &session->sync_state.keysync.challenge;
    9.20 -    TID_t *t2 = &session->own_sync_state.challenge;
    9.21 +    TID_t *t2 = &session->sync_state.own.challenge;
    9.22  
    9.23      *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    9.24  ||
    9.25  
    9.26 -condition sameChallenge
    9.27 -||
    9.28 -    TID_t *t1 = &session->sync_state.keysync.challenge;
    9.29 -    TID_t *t2 = &session->own_sync_state.challenge;
    9.30 -
    9.31 -    *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    9.32 -||
    9.33 -
    9.34 -condition sameTransaction
    9.35 +condition sameNegotiation
    9.36  ||
    9.37      TID_t *t1 = &session->sync_state.keysync.negotiation;
    9.38 -    TID_t *t2 = &session->own_sync_state.negotiation;
    9.39 +    TID_t *t2 = &session->sync_state.comm_partner.negotiation;
    9.40  
    9.41      // test if TID is identical
    9.42      *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
    9.43  ||
    9.44  
    9.45 -condition sameTransactionAndPartner
    9.46 +condition sameNegotiationAndPartner
    9.47  ||
    9.48      TID_t *t1 = &session->sync_state.keysync.negotiation;
    9.49 -    TID_t *t2 = &session->own_sync_state.negotiation;
    9.50 +    TID_t *t2 = &session->sync_state.comm_partner.negotiation;
    9.51  
    9.52 -    const char *s1 = session->sync_state.common.signature_fpr;
    9.53 -    const char *s2 = session->own_sync_state.signature_fpr;
    9.54 +    const char *s1 = session->sync_state.comm_partner.sender_fpr;
    9.55 +    const char *s2 = session->sync_state.transport.sender_fpr;
    9.56  
    9.57      // test if TID is identical
    9.58      *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0
    9.59 @@ -70,8 +62,8 @@
    9.60  
    9.61  condition keyElectionWon
    9.62  ||
    9.63 -    pEp_identity *from = session->sync_state.common.from;
    9.64 -    char *signature_fpr = session->sync_state.common.signature_fpr;
    9.65 +    pEp_identity *from = session->sync_state.transport.from;
    9.66 +    char *sender_fpr = session->sync_state.comm_partner.sender_fpr;
    9.67  
    9.68      assert(from && from->address && from->address[0] && from->user_id &&
    9.69              from->user_id[0]);
    9.70 @@ -91,8 +83,8 @@
    9.71          return PEP_ILLEGAL_VALUE;
    9.72      }
    9.73  
    9.74 -    size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
    9.75 -    *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
    9.76 +    size_t len = MIN(strlen(sender_fpr), strlen(me->fpr));
    9.77 +    *result = strncasecmp(sender_fpr, me->fpr, len) > 0;
    9.78      free_identity(me);
    9.79  ||
    9.80  
    9.81 @@ -101,10 +93,12 @@
    9.82  function "new_UUID" {
    9.83      param "dst";
    9.84      ||
    9.85 -        pEpUUID c;
    9.86 -        uuid_generate_random(c);
    9.87 +        {
    9.88 +            pEpUUID c;
    9.89 +            uuid_generate_random(c);
    9.90  
    9.91 -        OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
    9.92 +            OCTET_STRING_fromBuf(«$dst», (char *) c, 16);
    9.93 +        }
    9.94      ||
    9.95  }
    9.96  
    9.97 @@ -141,75 +135,98 @@
    9.98      ||
    9.99  }
   9.100  
   9.101 -action newChallenge {
   9.102 +action newChallengeAndNegotiationBase {
   9.103      // random new challenge
   9.104 -    call "new_UUID" with "dst" > &session->own_sync_state.challenge
   9.105 -    // store a copy of this challenge
   9.106 +    call "new_UUID" with "dst" > &session->sync_state.own.challenge
   9.107      call "copy_UUID" {
   9.108 -        with "src" > &session->own_sync_state.challenge
   9.109 -        with "dst" > &session->sync_state.common.challenge
   9.110 +        with "src" > &session->sync_state.own.challenge
   9.111 +        with "dst" > &session->sync_state.keysync.challenge
   9.112 +    }
   9.113 +
   9.114 +    // this is the random data we are using as a base
   9.115 +    call "new_UUID" with "dst" > &session->sync_state.own.negotiation
   9.116 +||
   9.117 +    memset(session->sync_state.keysync.negotiation.buf, 0,
   9.118 +            session->sync_state.keysync.negotiation.size);
   9.119 +    memset(session->sync_state.comm_partner.negotiation.buf, 0,
   9.120 +            session->sync_state.comm_partner.negotiation.size);
   9.121 +||
   9.122 +}
   9.123 +
   9.124 +action useOwnChallenge call "copy_UUID" {
   9.125 +    with "src" > &session->sync_state.own.challenge
   9.126 +    with "dst" > &session->sync_state.keysync.challenge
   9.127 +}
   9.128 +
   9.129 +action openNegotiation {
   9.130 +||
   9.131 +    // sender key must be stable while transaction
   9.132 +
   9.133 +    // we take the actual signature of the last message and store it in our
   9.134 +    // state for the comm partner
   9.135 +    assert(session->sync_state.transport.sender_fpr);
   9.136 +
   9.137 +    free(session->sync_state.comm_partner.sender_fpr);
   9.138 +
   9.139 +    session->sync_state.comm_partner.sender_fpr
   9.140 +            = strdup(session->sync_state.transport.sender_fpr);
   9.141 +    assert(session->sync_state.comm_partner.sender_fpr);
   9.142 +    if (!session->sync_state.comm_partner.sender_fpr)
   9.143 +        return PEP_OUT_OF_MEMORY;
   9.144 +
   9.145 +    // we need a unique TID for the Negotiation with each single comm_partner
   9.146 +    // we identify the comm_partners by their Challenge
   9.147 +    // we derive the actual Negotiation TID by having random data and XORing it
   9.148 +    // with comm_partner's Challenge
   9.149 +
   9.150 +    // copy Negotiation base into buffer
   9.151 +
   9.152 +||
   9.153 +    call "copy_UUID" {
   9.154 +        with "src" > &session->sync_state.own.negotiation
   9.155 +        with "dst" > &session->sync_state.keysync.negotiation
   9.156 +    }
   9.157 +||
   9.158 +
   9.159 +    // we're XORing this with the challenge of the comm_partner, which is in
   9.160 +    // the buffer already
   9.161 +
   9.162 +||
   9.163 +    call "xor_UUID" {
   9.164 +        with "src" > &session->sync_state.keysync.challenge
   9.165 +        with "dst" > &session->sync_state.keysync.negotiation
   9.166 +    }
   9.167 +||
   9.168 +
   9.169 +    // this is the Negotiation's TID for this comm_partner
   9.170 +
   9.171 +||
   9.172 +    call "copy_UUID" {
   9.173 +        with "src" > &session->sync_state.keysync.negotiation
   9.174 +        with "dst" > &session->sync_state.comm_partner.negotiation
   9.175      }
   9.176  }
   9.177  
   9.178 -action replyChallenge call "copy_UUID" {
   9.179 -    with "src" > &session->sync_state.keysync.challenge
   9.180 -    with "dst" > &session->own_sync_state.challenge
   9.181 -}
   9.182 -
   9.183 -action useOwnChallenge call "copy_UUID" {
   9.184 -    with "src" > &session->sync_state.common.challenge
   9.185 -    with "dst" > &session->own_sync_state.challenge
   9.186 -}
   9.187 -
   9.188 -action newTransaction {
   9.189 +action storeNegotiation {
   9.190  ||
   9.191      // sender key must be stable while transaction
   9.192 -    assert(session->sync_state.common.signature_fpr);
   9.193 -    free(session->own_sync_state.signature_fpr);
   9.194 -    session->own_sync_state.signature_fpr
   9.195 -            = strdup(session->sync_state.common.signature_fpr);
   9.196 -    assert(session->own_sync_state.signature_fpr);
   9.197 -    if (!session->own_sync_state.signature_fpr)
   9.198 -        return PEP_OUT_OF_MEMORY;
   9.199  
   9.200 -||
   9.201 -    call "copy_UUID" {
   9.202 -        with "src" > &session->sync_state.keysync.challenge
   9.203 -        with "dst" > &session->sync_state.keysync.negotiation
   9.204 -    }
   9.205 -    call "xor_UUID" {
   9.206 -        with "src" > &session->own_sync_state.challenge
   9.207 -        with "dst" > &session->sync_state.keysync.negotiation
   9.208 -    }
   9.209 -    call "copy_UUID" {
   9.210 -        with "src" > &session->sync_state.keysync.negotiation
   9.211 -        with "dst" > &session->own_sync_state.negotiation
   9.212 -    }
   9.213 -}
   9.214 +    // we take the actual signature of the last message and store it in our
   9.215 +    // state for the comm partner
   9.216 +    assert(session->sync_state.transport.sender_fpr);
   9.217  
   9.218 -action closeTransaction
   9.219 -||
   9.220 -    memset(session->sync_state.keysync.negotiation.buf, 0,
   9.221 -            session->sync_state.keysync.negotiation.size);
   9.222 -    memset(session->own_sync_state.negotiation.buf, 0,
   9.223 -            session->own_sync_state.negotiation.size);
   9.224 -||
   9.225 +    free(session->sync_state.comm_partner.sender_fpr);
   9.226  
   9.227 -action storeTransaction {
   9.228 -||
   9.229 -    // sender key must be stable while transaction
   9.230 -    assert(session->sync_state.common.signature_fpr);
   9.231 -    free(session->own_sync_state.signature_fpr);
   9.232 -    session->own_sync_state.signature_fpr
   9.233 -            = strdup(session->sync_state.common.signature_fpr);
   9.234 -    assert(session->own_sync_state.signature_fpr);
   9.235 -    if (!session->own_sync_state.signature_fpr)
   9.236 +    session->sync_state.comm_partner.sender_fpr
   9.237 +            = strdup(session->sync_state.transport.sender_fpr);
   9.238 +    assert(session->sync_state.comm_partner.sender_fpr);
   9.239 +    if (!session->sync_state.comm_partner.sender_fpr)
   9.240          return PEP_OUT_OF_MEMORY;
   9.241  
   9.242  ||
   9.243      call "copy_UUID" {
   9.244          with "src" > &session->sync_state.keysync.negotiation
   9.245 -        with "dst" > &session->own_sync_state.negotiation
   9.246 +        with "dst" > &session->sync_state.comm_partner.negotiation
   9.247      }
   9.248  }
   9.249  
   9.250 @@ -239,11 +256,11 @@
   9.251      ||
   9.252      otherwise
   9.253      ||
   9.254 -        assert(session->sync_state.common.from);
   9.255 -        if (!session->sync_state.common.from)
   9.256 +        assert(session->sync_state.transport.from);
   9.257 +        if (!session->sync_state.transport.from)
   9.258              return PEP_ILLEGAL_VALUE;
   9.259  
   9.260 -        pEp_identity *from = session->sync_state.common.from;
   9.261 +        pEp_identity *from = session->sync_state.transport.from;
   9.262          pEp_identity *me = NULL;
   9.263          PEP_STATUS status = get_identity(session, from->address, from->user_id, &me);
   9.264          assert(status == PEP_STATUS_OK);
   9.265 @@ -262,10 +279,10 @@
   9.266              return PEP_OUT_OF_MEMORY;
   9.267          }
   9.268  
   9.269 -        assert(session->sync_state.common.signature_fpr);
   9.270 -        if (session->sync_state.common.signature_fpr) {
   9.271 +        assert(session->sync_state.comm_partner.sender_fpr);
   9.272 +        if (session->sync_state.comm_partner.sender_fpr) {
   9.273              free(partner->fpr);
   9.274 -            partner->fpr = strdup(session->sync_state.common.signature_fpr);
   9.275 +            partner->fpr = strdup(session->sync_state.comm_partner.sender_fpr);
   9.276              if (!partner->fpr) {
   9.277                  free_identity(me);
   9.278                  free_identity(partner);
   9.279 @@ -323,9 +340,9 @@
   9.280      if (status)
   9.281          return status;
   9.282  
   9.283 -    if (session->own_sync_state.own_keys)
   9.284 -        free_stringlist(session->own_sync_state.own_keys);
   9.285 -    session->own_sync_state.own_keys = own_keys;
   9.286 +    if (session->sync_state.own.keys)
   9.287 +        free_stringlist(session->sync_state.own.keys);
   9.288 +    session->sync_state.own.keys = own_keys;
   9.289  
   9.290      identity_list *il;
   9.291      status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
   9.292 @@ -359,7 +376,7 @@
   9.293      PEP_STATUS status = PEP_STATUS_OK;
   9.294  
   9.295      // set flag for current keys
   9.296 -    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
   9.297 +    for (identity_list *il = session->sync_state.own.identities; il && il->ident ; il = il->next) {
   9.298          if (!(il->ident->flags && PEP_idf_not_for_sync)) {
   9.299              status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
   9.300              if (status)
   9.301 @@ -373,7 +390,7 @@
   9.302      PEP_STATUS status = PEP_STATUS_OK;
   9.303  
   9.304      // set flag for current keys
   9.305 -    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
   9.306 +    for (identity_list *il = session->sync_state.own.identities; il && il->ident ; il = il->next) {
   9.307          if (!(il->ident->flags && PEP_idf_not_for_sync)) {
   9.308              status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
   9.309              if (status)
   9.310 @@ -385,10 +402,10 @@
   9.311      if (!il)
   9.312          return PEP_OUT_OF_MEMORY;
   9.313  
   9.314 -    for (il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
   9.315 +    for (il = session->sync_state.own.identities; il && il->ident ; il = il->next) {
   9.316          // replace partner's user_id with own user_id
   9.317          free(il->ident->user_id);
   9.318 -        il->ident->user_id = strdup(session->sync_state.common.from->user_id);
   9.319 +        il->ident->user_id = strdup(session->sync_state.transport.from->user_id);
   9.320          if (!il->ident->user_id) {
   9.321              free_identity_list(il);
   9.322              return PEP_OUT_OF_MEMORY;
   9.323 @@ -412,33 +429,40 @@
   9.324  
   9.325  action trustThisKey
   9.326  ||
   9.327 -    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
   9.328 -    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
   9.329 +    assert(session->sync_state.transport.from && session->sync_state.comm_partner.sender_fpr);
   9.330 +    if (!(session->sync_state.transport.from && session->sync_state.comm_partner.sender_fpr))
   9.331          return PEP_ILLEGAL_VALUE;
   9.332  
   9.333 -    pEp_identity *ident = session->sync_state.common.from;
   9.334 +    pEp_identity *ident = identity_dup(session->sync_state.transport.from);
   9.335 +    if (!ident)
   9.336 +        return PEP_OUT_OF_MEMORY;
   9.337      free(ident->fpr);
   9.338 -    ident->fpr = strdup(session->sync_state.common.signature_fpr);
   9.339 +    ident->fpr = strdup(session->sync_state.comm_partner.sender_fpr);
   9.340      assert(ident->fpr);
   9.341 -    if (!ident->fpr)
   9.342 +    if (!ident->fpr) {
   9.343 +        free_identity(ident);
   9.344          return PEP_OUT_OF_MEMORY;
   9.345 +    }
   9.346  
   9.347      PEP_STATUS status = trust_own_key(session, ident);
   9.348 -    if (status)
   9.349 +    if (status) {
   9.350 +        free_identity(ident);
   9.351          return status;
   9.352 +    }
   9.353  
   9.354      OCTET_STRING_fromBuf(&session->sync_state.keysync.key, ident->fpr, strlen(ident->fpr));
   9.355 +    free_identity(ident);
   9.356  ||
   9.357  
   9.358  action untrustThisKey
   9.359  ||
   9.360 -    assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
   9.361 -    if (!(session->sync_state.common.from && session->sync_state.common.signature_fpr))
   9.362 +    assert(session->sync_state.transport.from && session->sync_state.comm_partner.sender_fpr);
   9.363 +    if (!(session->sync_state.transport.from && session->sync_state.comm_partner.sender_fpr))
   9.364          return PEP_ILLEGAL_VALUE;
   9.365  
   9.366 -    pEp_identity *ident = session->sync_state.common.from;
   9.367 +    pEp_identity *ident = session->sync_state.transport.from;
   9.368      free(ident->fpr);
   9.369 -    ident->fpr = strdup(session->sync_state.common.signature_fpr);
   9.370 +    ident->fpr = strdup(session->sync_state.comm_partner.sender_fpr);
   9.371      assert(ident->fpr);
   9.372      if (!ident->fpr)
   9.373          return PEP_OUT_OF_MEMORY;
    10.1 --- a/sync/gen_message_func.ysl2	Thu May 30 02:16:16 2019 +0200
    10.2 +++ b/sync/gen_message_func.ysl2	Thu May 30 02:16:49 2019 +0200
    10.3 @@ -39,32 +39,36 @@
    10.4  // state
    10.5  
    10.6  struct «@name»_state_s {
    10.7 -    // common buffer for all types of «@name» messages
    10.8 +    // own state
    10.9  
   10.10 -    struct common_state_s {
   10.11 -        // intermediate store own challenge
   10.12 -        TID_t challenge;
   10.13 +    struct own_«@name»_state_s {
   10.14 +        stringlist_t *keys;
   10.15 +        identity_list *identities;
   10.16  
   10.17 -        // transport data
   10.18 +        // TIDs we're using ourselves
   10.19 +        `` for "func:distinctName(fsm/message/field[@type='TID'])" |>> «func:ctype()» «@name»;
   10.20 +    } own;
   10.21 +
   10.22 +    // state we learned about our communication partner
   10.23 +
   10.24 +    struct comm_partner_state_s {
   10.25 +        // transport data we expect
   10.26 +        char *sender_fpr;
   10.27 +
   10.28 +        // TIDs our comm partner wants to have
   10.29 +        `` for "func:distinctName(fsm/message/field[@type='TID'])" |>> «func:ctype()» «@name»;
   10.30 +    } comm_partner;
   10.31 +
   10.32 +    // input buffer for actual transport data coming in
   10.33 +
   10.34 +    struct transport_data_s {
   10.35 +        // transport data we got
   10.36          pEp_identity *from;
   10.37 -        char *signature_fpr;
   10.38 -    } common;
   10.39 +        char *sender_fpr;
   10.40 +    } transport;
   10.41      `` apply "fsm", mode=state
   10.42  };
   10.43  
   10.44 -// own state
   10.45 -
   10.46 -struct own_«@name»_state_s {
   10.47 -    stringlist_t *own_keys;
   10.48 -    identity_list *own_identities;
   10.49 -
   10.50 -    `` if "func:distinctName(fsm/message/field[@type='TID'])" |> // active TIDs
   10.51 -    `` for "func:distinctName(fsm/message/field[@type='TID'])" |> «func:ctype()» «@name»;
   10.52 -
   10.53 -    // transport data
   10.54 -    char *signature_fpr;
   10.55 -};
   10.56 -
   10.57  void free_«@name»_state(PEP_SESSION session);
   10.58  
   10.59  // functions for protocol «@name»
   10.60 @@ -86,7 +90,7 @@
   10.61  template "fsm", mode=state
   10.62  ||
   10.63  
   10.64 -// buffer for «@name» messages
   10.65 +// input/output buffer for «@name» messages
   10.66  
   10.67  struct _«@name»_state_s {
   10.68      int state;
   10.69 @@ -113,21 +117,46 @@
   10.70      if (!session)
   10.71          return;
   10.72  
   10.73 -    free_identity(session->«yml:lcase(@name)»_state.common.from);
   10.74 -    free(session->«yml:lcase(@name)»_state.common.signature_fpr);
   10.75 -    free_stringlist(session->own_«yml:lcase(@name)»_state.own_keys);
   10.76 -    free_identity_list(session->own_«yml:lcase(@name)»_state.own_identities);
   10.77 -    session->own_«yml:lcase(@name)»_state.own_keys = NULL;
   10.78 -    session->own_«yml:lcase(@name)»_state.own_identities = NULL;
   10.79 +    // own state
   10.80 +
   10.81 +    free_stringlist(session->«yml:lcase(@name)»_state.own.keys);
   10.82 +    session->«yml:lcase(@name)»_state.own.keys = NULL;
   10.83 +    free_identity_list(session->«yml:lcase(@name)»_state.own.identities);
   10.84 +    session->«yml:lcase(@name)»_state.own.identities = NULL;
   10.85 +
   10.86 +    // TIDs we're using ourselves
   10.87 +||
   10.88 +    for "func:distinctName(fsm/message/field[@type='TID'])"
   10.89 +        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.own.«@name»);
   10.90 +||
   10.91 +
   10.92 +    // state we learned about our communication partner
   10.93 +
   10.94 +    free(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr);
   10.95 +    session->«yml:lcase(@name)»_state.comm_partner.sender_fpr = NULL;
   10.96 +
   10.97 +    // TIDs our comm partner wants to have
   10.98 +||
   10.99 +    for "func:distinctName(fsm/message/field[@type='TID'])"
  10.100 +        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.comm_partner.«@name»);
  10.101 +||
  10.102 +
  10.103 +    // buffer for transport data
  10.104 +
  10.105 +    free_identity(session->«yml:lcase(@name)»_state.transport.from);
  10.106 +    session->«yml:lcase(@name)»_state.transport.from = NULL;
  10.107 +    free(session->«yml:lcase(@name)»_state.transport.sender_fpr);
  10.108 +    session->«yml:lcase(@name)»_state.transport.sender_fpr = NULL;
  10.109 +
  10.110 +    // message buffers
  10.111  
  10.112  ||
  10.113 -for "fsm"
  10.114 -    for "func:distinctName(message/field[not(func:basicType())])"
  10.115 -        |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
  10.116 -for "func:distinctName(fsm/message/field[@type='TID'])"
  10.117 -    |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->own_«yml:lcase(../../../@name)»_state.«@name»);
  10.118 +    for "fsm" {
  10.119 +        for "func:distinctName(message/field[not(substring(@type,1,1)=yml:lcase(substring(@type,1,1)))])"
  10.120 +            |> ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_«@type», &session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»);
  10.121 +        |
  10.122 +    }
  10.123  ||
  10.124 -
  10.125      memset(&session->«yml:lcase(@name)»_state, 0, sizeof(session->«yml:lcase(@name)»_state));
  10.126  }
  10.127  
  10.128 @@ -259,12 +288,7 @@
  10.129  
  10.130  template "field", mode=update_message {
  10.131      const "message_name", "yml:mixedCase(../@name)";
  10.132 -    const "state" choose {
  10.133 -        when "@type='TID'"
  10.134 -            > own_«yml:lcase(ancestor::protocol/@name)»_state
  10.135 -        otherwise
  10.136 -            > «yml:lcase(ancestor::protocol/@name)»_state.«yml:lcase(ancestor::fsm/@name)»
  10.137 -    }
  10.138 +    const "state" > «yml:lcase(ancestor::protocol/@name)»_state.«yml:lcase(ancestor::fsm/@name)»
  10.139  
  10.140      choose {
  10.141          when "func:basicType()" // copyable
    11.1 --- a/sync/gen_statemachine.ysl2	Thu May 30 02:16:16 2019 +0200
    11.2 +++ b/sync/gen_statemachine.ysl2	Thu May 30 02:16:49 2019 +0200
    11.3 @@ -38,7 +38,7 @@
    11.4  
    11.5              // transport data
    11.6              pEp_identity *from;
    11.7 -            char *signature_fpr;
    11.8 +            char *sender_fpr;
    11.9  
   11.10              identity_list *own_identities;
   11.11          } «@name»_event_t;
   11.12 @@ -119,7 +119,7 @@
   11.13                  free_identity_list(ev->own_identities);
   11.14                  free_«@name»_message(ev->msg);
   11.15                  free_identity(ev->from);
   11.16 -                free(ev->signature_fpr);
   11.17 +                free(ev->sender_fpr);
   11.18                  free(ev);
   11.19              }
   11.20          }
   11.21 @@ -211,7 +211,7 @@
   11.22                      const char *data,
   11.23                      size_t size,
   11.24                      const pEp_identity *from,
   11.25 -                    const char *signature_fpr
   11.26 +                    const char *sender_fpr
   11.27                  );
   11.28  
   11.29              #ifdef __cplusplus
   11.30 @@ -328,7 +328,7 @@
   11.31                      const char *data,
   11.32                      size_t size,
   11.33                      const pEp_identity *from,
   11.34 -                    const char *signature_fpr
   11.35 +                    const char *sender_fpr
   11.36                  )
   11.37              {
   11.38                  assert(session && data && size);
   11.39 @@ -373,10 +373,10 @@
   11.40                      }
   11.41                  }
   11.42  
   11.43 -                if (signature_fpr) {
   11.44 -                    ev->signature_fpr = strdup(signature_fpr);
   11.45 -                    assert(ev->signature_fpr);
   11.46 -                    if (!ev->signature_fpr) {
   11.47 +                if (sender_fpr) {
   11.48 +                    ev->sender_fpr = strdup(sender_fpr);
   11.49 +                    assert(ev->sender_fpr);
   11.50 +                    if (!ev->sender_fpr) {
   11.51                          status = PEP_OUT_OF_MEMORY;
   11.52                          goto the_end;
   11.53                      }
   11.54 @@ -447,8 +447,8 @@
   11.55  
   11.56                      // these go anycast; previously used address is sticky (unicast)
   11.57                      `` for "fsm/message[@type='anycast']" |>> case «../@name»_PR_«yml:mixedCase(@name)»:
   11.58 -                        if (!session->«yml:lcase(@name)»_state.common.from `> |`|
   11.59 -                            (session->«yml:lcase(@name)»_state.common.from->flags &
   11.60 +                        if (!session->«yml:lcase(@name)»_state.transport.from `> |`|
   11.61 +                            (session->«yml:lcase(@name)»_state.transport.from->flags &
   11.62                              PEP_idf_not_for_«yml:lcase(@name)»)) {
   11.63  
   11.64                              // no address available yet, try to find one
   11.65 @@ -468,7 +468,7 @@
   11.66                              }
   11.67                          }
   11.68                          else {
   11.69 -                            pEp_identity *channel = identity_dup(session->«yml:lcase(@name)»_state.common.from);
   11.70 +                            pEp_identity *channel = identity_dup(session->«yml:lcase(@name)»_state.transport.from);
   11.71                              if (!channel) {
   11.72                                  status = PEP_OUT_OF_MEMORY;
   11.73                                  goto the_end;
   11.74 @@ -521,13 +521,13 @@
   11.75                      `` for "fsm/message[@security='untrusted']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
   11.76                              // add fpr of key of comm partner
   11.77  
   11.78 -                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr);
   11.79 -                            if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
   11.80 +                            assert(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr);
   11.81 +                            if (!session->«yml:lcase(@name)»_state.comm_partner.sender_fpr) {
   11.82                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   11.83                                  goto the_end;
   11.84                              }
   11.85  
   11.86 -                            extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
   11.87 +                            extra = new_stringlist(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr);
   11.88                              if (!extra) {
   11.89                                  status = PEP_OUT_OF_MEMORY;
   11.90                                  goto the_end;
   11.91 @@ -556,11 +556,11 @@
   11.92                              break;
   11.93  
   11.94                      `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
   11.95 -                            // check if this is the key of a former negotiation
   11.96 +                            // check if we had a former negotiation
   11.97  
   11.98                              transaction = false;
   11.99 -                            for (int i=0; i < session->own_«yml:lcase(@name)»_state.negotiation.size; i++) {
  11.100 -                                if (session->own_«yml:lcase(@name)»_state.negotiation.buf[i]) {
  11.101 +                            for (int i=0; i < session->«yml:lcase(@name)»_state.own.negotiation.size; i++) {
  11.102 +                                if (session->«yml:lcase(@name)»_state.own.negotiation.buf[i]) {
  11.103                                      transaction = true;
  11.104                                      break;
  11.105                                  }
  11.106 @@ -573,12 +573,12 @@
  11.107                              // secret keys
  11.108  
  11.109                              if (transaction) {
  11.110 -                                assert(session->own_«yml:lcase(@name)»_state.signature_fpr &&
  11.111 -                                    session->«yml:lcase(@name)»_state.common.from &&
  11.112 -                                    session->«yml:lcase(@name)»_state.common.from->user_id);
  11.113 -                                if (!(session->own_«yml:lcase(@name)»_state.signature_fpr &&
  11.114 -                                        session->«yml:lcase(@name)»_state.common.from &&
  11.115 -                                        session->«yml:lcase(@name)»_state.common.from->user_id))
  11.116 +                                assert(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr &&
  11.117 +                                    session->«yml:lcase(@name)»_state.transport.from &&
  11.118 +                                    session->«yml:lcase(@name)»_state.transport.from->user_id);
  11.119 +                                if (!(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr &&
  11.120 +                                        session->«yml:lcase(@name)»_state.transport.from &&
  11.121 +                                        session->«yml:lcase(@name)»_state.transport.from->user_id))
  11.122                                  {
  11.123                                      status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
  11.124                                      goto the_end;
  11.125 @@ -587,8 +587,8 @@
  11.126                                  // test if this is a green channel
  11.127  
  11.128                                  pEp_identity *ident = new_identity(NULL,
  11.129 -                                        session->own_«yml:lcase(@name)»_state.signature_fpr,
  11.130 -                                        session->«yml:lcase(@name)»_state.common.from->user_id,
  11.131 +                                        session->«yml:lcase(@name)»_state.comm_partner.sender_fpr,
  11.132 +                                        session->«yml:lcase(@name)»_state.transport.from->user_id,
  11.133                                          NULL
  11.134                                      );
  11.135                                  if (!ident) {
  11.136 @@ -612,7 +612,7 @@
  11.137  
  11.138                                  bool is_own_key = false;
  11.139                                  status = own_key_is_listed(session,
  11.140 -                                        session->own_«yml:lcase(@name)»_state.signature_fpr,
  11.141 +                                        session->«yml:lcase(@name)»_state.comm_partner.sender_fpr,
  11.142                                          &is_own_key);
  11.143                                  assert(!status);
  11.144                                  if (status)
  11.145 @@ -625,7 +625,7 @@
  11.146  
  11.147                                  // if so add key of comm partner to extra keys
  11.148  
  11.149 -                                extra = new_stringlist(session->own_«yml:lcase(@name)»_state.signature_fpr);
  11.150 +                                extra = new_stringlist(session->«yml:lcase(@name)»_state.comm_partner.sender_fpr);
  11.151                                  if (!extra) {
  11.152                                      status = PEP_OUT_OF_MEMORY;
  11.153                                      goto the_end;
  11.154 @@ -660,7 +660,7 @@
  11.155                                                 // if we include this in the size, libetpan will null terminate and 
  11.156                                                 // go bananas. We can't have a NUL in the mime text.
  11.157  
  11.158 -                            for (stringlist_t *sl = session->own_«yml:lcase(@name)»_state.own_keys;
  11.159 +                            for (stringlist_t *sl = session->«yml:lcase(@name)»_state.own.keys;
  11.160                                      sl && sl->value ; sl = sl->next)
  11.161                              {
  11.162                                  char *_key_data = NULL;
  11.163 @@ -766,6 +766,8 @@
  11.164                  free(data);
  11.165                  free(key_data);
  11.166                  free_«@name»_message(msg);
  11.167 +                if (status)
  11.168 +                    SERVICE_ERROR_LOG(session, "send_«@name»_message()", status);
  11.169                  return status;
  11.170              }
  11.171  
  11.172 @@ -806,22 +808,22 @@
  11.173                  // update transport data
  11.174  
  11.175                  if (ev->from) {
  11.176 -                    free_identity(session->«yml:lcase(@name)»_state.common.from);
  11.177 -                    session->«yml:lcase(@name)»_state.common.from = ev->from;
  11.178 +                    free_identity(session->«yml:lcase(@name)»_state.transport.from);
  11.179 +                    session->«yml:lcase(@name)»_state.transport.from = ev->from;
  11.180                      ev->from = NULL;
  11.181                  }
  11.182  
  11.183 -                if (ev->signature_fpr) {
  11.184 -                    free(session->«yml:lcase(@name)»_state.common.signature_fpr);
  11.185 -                    session->«yml:lcase(@name)»_state.common.signature_fpr = ev->signature_fpr;
  11.186 -                    ev->signature_fpr = NULL;
  11.187 +                if (ev->sender_fpr) {
  11.188 +                    free(session->«yml:lcase(@name)»_state.transport.sender_fpr);
  11.189 +                    session->«yml:lcase(@name)»_state.transport.sender_fpr = ev->sender_fpr;
  11.190 +                    ev->sender_fpr = NULL;
  11.191                  }
  11.192  
  11.193                  // update own identities
  11.194  
  11.195                  if (ev->own_identities && ev->own_identities->ident) {
  11.196 -                    free_identity_list(session->own_«yml:lcase(@name)»_state.own_identities);
  11.197 -                    session->own_«yml:lcase(@name)»_state.own_identities = ev->own_identities;
  11.198 +                    free_identity_list(session->«yml:lcase(@name)»_state.own.identities);
  11.199 +                    session->«yml:lcase(@name)»_state.own.identities = ev->own_identities;
  11.200                      ev->own_identities = NULL;
  11.201                  }
  11.202  
  11.203 @@ -899,7 +901,7 @@
  11.204          if "position()=1" |>> // these messages require a detached signature
  11.205          ||
  11.206                  case «../@name»_PR_«yml:mixedCase(@name)»:
  11.207 -                    if (!signature_fpr) {
  11.208 +                    if (!sender_fpr) {
  11.209                          status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  11.210                          goto the_end;
  11.211                      }
  11.212 @@ -929,7 +931,7 @@
  11.213                          status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  11.214                          goto the_end;
  11.215                      }
  11.216 -                    status = own_key_is_listed(session, signature_fpr, &is_own_key);
  11.217 +                    status = own_key_is_listed(session, sender_fpr, &is_own_key);
  11.218                      if (status)
  11.219                          goto the_end;
  11.220                      if (!is_own_key) {
    12.1 --- a/sync/sync.fsm	Thu May 30 02:16:16 2019 +0200
    12.2 +++ b/sync/sync.fsm	Thu May 30 02:16:49 2019 +0200
    12.3 @@ -23,8 +23,7 @@
    12.4  
    12.5          state Sole timeout=off {
    12.6              on Init {
    12.7 -                do closeTransaction;
    12.8 -                do newChallenge;
    12.9 +                do newChallengeAndNegotiationBase;
   12.10                  do showBeingSole;
   12.11                  send Beacon;
   12.12              }
   12.13 @@ -43,13 +42,13 @@
   12.14                  }
   12.15                  else {
   12.16                      if weAreFirst {
   12.17 +                        do useOwnChallenge;
   12.18                          send Beacon;
   12.19                      }
   12.20                      else /* we are second */ {
   12.21 -                        do newTransaction;
   12.22 +                        do openNegotiation;
   12.23                          do tellWeAreNotGrouped;
   12.24                          // second is sending NegotiationRequest
   12.25 -                        do replyChallenge; // partner's challenge
   12.26                          send NegotiationRequest;
   12.27                          do useOwnChallenge;
   12.28                      }
   12.29 @@ -57,23 +56,24 @@
   12.30              }
   12.31  
   12.32              on NegotiationRequest {
   12.33 -                if challengeAccepted {
   12.34 -                    if sameTransaction {
   12.35 +                if sameChallenge { // challenge accepted
   12.36 +                    if sameNegotiation {
   12.37                          // this is our own NegotiationRequest; ignore
   12.38                      }
   12.39                      else {
   12.40                          // first is receiving NegotiationRequest
   12.41 -                        do storeTransaction;
   12.42 +                        do storeNegotiation;
   12.43                          // first is sending NegotiationOpen
   12.44                          send NegotiationOpen;
   12.45                          if partnerIsGrouped
   12.46                              go HandshakingWithGroup;
   12.47 -                        go HandshakingNewFirst;
   12.48 +                        else
   12.49 +                            go HandshakingNewFirst;
   12.50                      }
   12.51                  }
   12.52              }
   12.53  
   12.54 -            on NegotiationOpen if sameTransactionAndPartner {
   12.55 +            on NegotiationOpen if sameNegotiationAndPartner {
   12.56                  // second is receiving NegotiationOpen
   12.57                  go HandshakingNewSecond;
   12.58              }
   12.59 @@ -90,7 +90,7 @@
   12.60                  go Sole;
   12.61              }
   12.62  
   12.63 -            on Rollback if sameTransactionAndPartner
   12.64 +            on Rollback if sameNegotiationAndPartner
   12.65                  go Sole;
   12.66  
   12.67              // Reject is CommitReject
   12.68 @@ -100,7 +100,7 @@
   12.69                  go End;
   12.70              }
   12.71  
   12.72 -            on CommitReject if sameTransactionAndPartner {
   12.73 +            on CommitReject if sameNegotiationAndPartner {
   12.74                  do disable;
   12.75                  go End;
   12.76              }
   12.77 @@ -113,7 +113,7 @@
   12.78              }
   12.79  
   12.80              // got a CommitAccept from second
   12.81 -            on CommitAcceptSecond if sameTransactionAndPartner
   12.82 +            on CommitAcceptSecond if sameNegotiationAndPartner
   12.83                  go HandshakingNewPhase2First;
   12.84          }
   12.85  
   12.86 @@ -128,7 +128,7 @@
   12.87                  go Sole;
   12.88              }
   12.89  
   12.90 -            on Rollback if sameTransactionAndPartner
   12.91 +            on Rollback if sameNegotiationAndPartner
   12.92                  go Sole;
   12.93  
   12.94              // Reject is CommitReject
   12.95 @@ -138,7 +138,7 @@
   12.96                  go End;
   12.97              }
   12.98  
   12.99 -            on CommitReject if sameTransactionAndPartner {
  12.100 +            on CommitReject if sameNegotiationAndPartner {
  12.101                  do disable;
  12.102                  go End;
  12.103              }
  12.104 @@ -151,40 +151,40 @@
  12.105              }
  12.106  
  12.107              // got a CommitAccept from first
  12.108 -            on CommitAcceptFirst if sameTransactionAndPartner
  12.109 +            on CommitAcceptFirst if sameNegotiationAndPartner
  12.110                  go HandshakingNewPhase2Second;
  12.111          }
  12.112  
  12.113          state HandshakingNewPhase1First {
  12.114 -            on Rollback if sameTransactionAndPartner {
  12.115 +            on Rollback if sameNegotiationAndPartner {
  12.116                  do untrustThisKey;
  12.117                  go Sole;
  12.118              }
  12.119              
  12.120 -            on CommitReject if sameTransactionAndPartner {
  12.121 +            on CommitReject if sameNegotiationAndPartner {
  12.122                  do untrustThisKey;
  12.123                  do disable;
  12.124                  go End;
  12.125              }
  12.126  
  12.127 -            on CommitAcceptSecond if sameTransactionAndPartner {
  12.128 +            on CommitAcceptSecond if sameNegotiationAndPartner {
  12.129                  go NewGroupFirst;
  12.130              }
  12.131          }
  12.132  
  12.133          state HandshakingNewPhase1Second {
  12.134 -            on Rollback if sameTransactionAndPartner {
  12.135 +            on Rollback if sameNegotiationAndPartner {
  12.136                  do untrustThisKey;
  12.137                  go Sole;
  12.138              }
  12.139              
  12.140 -            on CommitReject if sameTransactionAndPartner {
  12.141 +            on CommitReject if sameNegotiationAndPartner {
  12.142                  do untrustThisKey;
  12.143                  do disable;
  12.144                  go End;
  12.145              }
  12.146  
  12.147 -            on CommitAcceptFirst if sameTransactionAndPartner {
  12.148 +            on CommitAcceptFirst if sameNegotiationAndPartner {
  12.149                  go NewGroupSecond;
  12.150              }
  12.151          }
  12.152 @@ -265,8 +265,7 @@
  12.153  
  12.154          state Grouped timeout=off {
  12.155              on Init {
  12.156 -                do closeTransaction;
  12.157 -                do newChallenge;
  12.158 +                do newChallengeAndNegotiationBase;
  12.159                  do showBeingInGroup;
  12.160              }
  12.161  
  12.162 @@ -279,14 +278,13 @@
  12.163              }
  12.164  
  12.165              on Beacon {
  12.166 -                do newTransaction;
  12.167 +                do openNegotiation;
  12.168                  do tellWeAreGrouped;
  12.169 -                do replyChallenge; // partner's challenge
  12.170                  send NegotiationRequest;
  12.171                  do useOwnChallenge;
  12.172              }
  12.173  
  12.174 -            on NegotiationOpen if sameTransactionAndPartner
  12.175 +            on NegotiationOpen if sameNegotiationAndPartner
  12.176                  go HandshakingGrouped;
  12.177  
  12.178              on GroupTrustThisKey {
  12.179 @@ -305,7 +303,7 @@
  12.180                  go Sole;
  12.181              }
  12.182  
  12.183 -            on Rollback if sameTransactionAndPartner
  12.184 +            on Rollback if sameNegotiationAndPartner
  12.185                  go Sole;
  12.186  
  12.187              // Reject is CommitReject
  12.188 @@ -315,7 +313,7 @@
  12.189                  go End;
  12.190              }
  12.191  
  12.192 -            on CommitReject if sameTransactionAndPartner {
  12.193 +            on CommitReject if sameNegotiationAndPartner {
  12.194                  do disable;
  12.195                  go End;
  12.196              }
  12.197 @@ -327,20 +325,20 @@
  12.198                  go HandshakingJoinPhase1;
  12.199              }
  12.200  
  12.201 -            on CommitAcceptForGroup if sameTransactionAndPartner
  12.202 +            on CommitAcceptForGroup if sameNegotiationAndPartner
  12.203                  go HandshakingJoinPhase2;
  12.204          }
  12.205  
  12.206          state HandshakingJoinPhase1 {
  12.207 -            on Rollback if sameTransactionAndPartner
  12.208 +            on Rollback if sameNegotiationAndPartner
  12.209                  go Sole;
  12.210              
  12.211 -            on CommitReject if sameTransactionAndPartner {
  12.212 +            on CommitReject if sameNegotiationAndPartner {
  12.213                  do disable;
  12.214                  go End;
  12.215              }
  12.216  
  12.217 -            on CommitAcceptForGroup if sameTransactionAndPartner {
  12.218 +            on CommitAcceptForGroup if sameNegotiationAndPartner {
  12.219                  go JoinGroup;
  12.220              }
  12.221          }
  12.222 @@ -387,7 +385,7 @@
  12.223                  go Grouped;
  12.224              }
  12.225  
  12.226 -            on Rollback if sameTransactionAndPartner
  12.227 +            on Rollback if sameNegotiationAndPartner
  12.228                  go Grouped;
  12.229  
  12.230              // Reject is CommitReject
  12.231 @@ -396,7 +394,7 @@
  12.232                  go Grouped;
  12.233              }
  12.234  
  12.235 -            on CommitReject if sameTransactionAndPartner
  12.236 +            on CommitReject if sameNegotiationAndPartner
  12.237                  go Grouped;
  12.238  
  12.239              // Accept is Phase1Commit
  12.240 @@ -407,7 +405,7 @@
  12.241                  go HandshakingGroupedPhase1;
  12.242              }
  12.243  
  12.244 -            on CommitAccept if sameTransactionAndPartner
  12.245 +            on CommitAccept if sameNegotiationAndPartner
  12.246                  go HandshakingGroupedPhase2;
  12.247  
  12.248              on GroupTrustThisKey {
  12.249 @@ -417,7 +415,7 @@
  12.250  
  12.251              on CommitAcceptForGroup {
  12.252                  do showDeviceAdded;
  12.253 -                if sameTransactionAndPartner {
  12.254 +                if sameNegotiationAndPartner {
  12.255                      do hideHandshakeDialog;
  12.256                      go Grouped;
  12.257                  }
  12.258 @@ -428,13 +426,13 @@
  12.259          }
  12.260  
  12.261          state HandshakingGroupedPhase1 {
  12.262 -            on Rollback if sameTransactionAndPartner
  12.263 +            on Rollback if sameNegotiationAndPartner
  12.264                  go Grouped;
  12.265  
  12.266 -            on CommitReject if sameTransactionAndPartner
  12.267 +            on CommitReject if sameNegotiationAndPartner
  12.268                  go Grouped;
  12.269  
  12.270 -            on CommitAccept if sameTransactionAndPartner {
  12.271 +            on CommitAccept if sameNegotiationAndPartner {
  12.272                  send GroupKeys;
  12.273                  go Grouped;
  12.274              }
  12.275 @@ -445,7 +443,7 @@
  12.276  
  12.277              on CommitAcceptForGroup {
  12.278                  do showDeviceAdded;
  12.279 -                if sameTransactionAndPartner
  12.280 +                if sameNegotiationAndPartner
  12.281                      go Grouped;
  12.282              }
  12.283  
  12.284 @@ -477,7 +475,7 @@
  12.285  
  12.286              on CommitAcceptForGroup {
  12.287                  do showDeviceAdded;
  12.288 -                if sameTransactionAndPartner {
  12.289 +                if sameNegotiationAndPartner {
  12.290                      do hideHandshakeDialog;
  12.291                      go Grouped;
  12.292                  }
    13.1 --- a/test/src/engine_tests/URIAddressTests.cc	Thu May 30 02:16:16 2019 +0200
    13.2 +++ b/test/src/engine_tests/URIAddressTests.cc	Thu May 30 02:16:49 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);