merge sync
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Mon, 29 Apr 2019 12:15:53 +0200
branchsync
changeset 3571dd5d993af3c3
parent 3570 9720511325c2
parent 3569 de4e7af39556
child 3572 b5fab91365e7
merge
sync/sync_protocol.txt
sync/sync_ux.txt
test/src/SuiteMaker.cc
     1.1 --- a/build-windows/libpEpasn1/libpEpasn1.vcxproj	Mon Apr 29 12:15:05 2019 +0200
     1.2 +++ b/build-windows/libpEpasn1/libpEpasn1.vcxproj	Mon Apr 29 12:15:53 2019 +0200
     1.3 @@ -143,109 +143,10 @@
     1.4      <Text Include="ReadMe.txt" />
     1.5    </ItemGroup>
     1.6    <ItemGroup>
     1.7 -    <ClInclude Include="..\..\asn.1\asn_application.h" />
     1.8 -    <ClInclude Include="..\..\asn.1\asn_codecs.h" />
     1.9 -    <ClInclude Include="..\..\asn.1\asn_codecs_prim.h" />
    1.10 -    <ClInclude Include="..\..\asn.1\asn_internal.h" />
    1.11 -    <ClInclude Include="..\..\asn.1\asn_SEQUENCE_OF.h" />
    1.12 -    <ClInclude Include="..\..\asn.1\asn_SET_OF.h" />
    1.13 -    <ClInclude Include="..\..\asn.1\asn_system.h" />
    1.14 -    <ClInclude Include="..\..\asn.1\Beacon.h" />
    1.15 -    <ClInclude Include="..\..\asn.1\ber_decoder.h" />
    1.16 -    <ClInclude Include="..\..\asn.1\ber_tlv_length.h" />
    1.17 -    <ClInclude Include="..\..\asn.1\ber_tlv_tag.h" />
    1.18 -    <ClInclude Include="..\..\asn.1\BIT_STRING.h" />
    1.19 -    <ClInclude Include="..\..\asn.1\BOOLEAN.h" />
    1.20 -    <ClInclude Include="..\..\asn.1\CommitAccept.h" />
    1.21 -    <ClInclude Include="..\..\asn.1\CommitAcceptForGroup.h" />
    1.22 -    <ClInclude Include="..\..\asn.1\CommitReject.h" />
    1.23 -    <ClInclude Include="..\..\asn.1\constraints.h" />
    1.24 -    <ClInclude Include="..\..\asn.1\constr_CHOICE.h" />
    1.25 -    <ClInclude Include="..\..\asn.1\constr_SEQUENCE.h" />
    1.26 -    <ClInclude Include="..\..\asn.1\constr_SEQUENCE_OF.h" />
    1.27 -    <ClInclude Include="..\..\asn.1\constr_SET_OF.h" />
    1.28 -    <ClInclude Include="..\..\asn.1\constr_TYPE.h" />
    1.29 -    <ClInclude Include="..\..\asn.1\der_encoder.h" />
    1.30 -    <ClInclude Include="..\..\asn.1\GroupKeys.h" />
    1.31 -    <ClInclude Include="..\..\asn.1\GroupKeysAndClose.h" />
    1.32 -    <ClInclude Include="..\..\asn.1\GroupTrustThisKey.h" />
    1.33 -    <ClInclude Include="..\..\asn.1\HandshakeAnswer.h" />
    1.34 -    <ClInclude Include="..\..\asn.1\HandshakeRequest.h" />
    1.35 -    <ClInclude Include="..\..\asn.1\Hash.h" />
    1.36 -    <ClInclude Include="..\..\asn.1\Hex.h" />
    1.37 -    <ClInclude Include="..\..\asn.1\Identity.h" />
    1.38 -    <ClInclude Include="..\..\asn.1\IdentityList.h" />
    1.39 -    <ClInclude Include="..\..\asn.1\INTEGER.h" />
    1.40 -    <ClInclude Include="..\..\asn.1\ISO639-1.h" />
    1.41 -    <ClInclude Include="..\..\asn.1\KeySync.h" />
    1.42 -    <ClInclude Include="..\..\asn.1\NativeEnumerated.h" />
    1.43 -    <ClInclude Include="..\..\asn.1\NativeInteger.h" />
    1.44 -    <ClInclude Include="..\..\asn.1\OCTET_STRING.h" />
    1.45 -    <ClInclude Include="..\..\asn.1\per_decoder.h" />
    1.46 -    <ClInclude Include="..\..\asn.1\per_encoder.h" />
    1.47 -    <ClInclude Include="..\..\asn.1\per_opentype.h" />
    1.48 -    <ClInclude Include="..\..\asn.1\per_support.h" />
    1.49 -    <ClInclude Include="..\..\asn.1\PrintableString.h" />
    1.50 -    <ClInclude Include="..\..\asn.1\PString.h" />
    1.51 -    <ClInclude Include="..\..\asn.1\Rollback.h" />
    1.52 -    <ClInclude Include="..\..\asn.1\Sync.h" />
    1.53 -    <ClInclude Include="..\..\asn.1\TID.h" />
    1.54 -    <ClInclude Include="..\..\asn.1\UTF8String.h" />
    1.55 -    <ClInclude Include="..\..\asn.1\Version.h" />
    1.56 -    <ClInclude Include="..\..\asn.1\xer_decoder.h" />
    1.57 -    <ClInclude Include="..\..\asn.1\xer_encoder.h" />
    1.58 -    <ClInclude Include="..\..\asn.1\xer_support.h" />
    1.59 +    <ClInclude Include="..\..\asn.1\*.h" />
    1.60    </ItemGroup>
    1.61    <ItemGroup>
    1.62 -    <ClCompile Include="..\..\asn.1\asn_codecs_prim.c" />
    1.63 -    <ClCompile Include="..\..\asn.1\asn_SEQUENCE_OF.c" />
    1.64 -    <ClCompile Include="..\..\asn.1\asn_SET_OF.c" />
    1.65 -    <ClCompile Include="..\..\asn.1\Beacon.c" />
    1.66 -    <ClCompile Include="..\..\asn.1\ber_decoder.c" />
    1.67 -    <ClCompile Include="..\..\asn.1\ber_tlv_length.c" />
    1.68 -    <ClCompile Include="..\..\asn.1\ber_tlv_tag.c" />
    1.69 -    <ClCompile Include="..\..\asn.1\BIT_STRING.c" />
    1.70 -    <ClCompile Include="..\..\asn.1\BOOLEAN.c" />
    1.71 -    <ClCompile Include="..\..\asn.1\CommitAccept.c" />
    1.72 -    <ClCompile Include="..\..\asn.1\CommitAcceptForGroup.c" />
    1.73 -    <ClCompile Include="..\..\asn.1\CommitReject.c" />
    1.74 -    <ClCompile Include="..\..\asn.1\constraints.c" />
    1.75 -    <ClCompile Include="..\..\asn.1\constr_CHOICE.c" />
    1.76 -    <ClCompile Include="..\..\asn.1\constr_SEQUENCE.c" />
    1.77 -    <ClCompile Include="..\..\asn.1\constr_SEQUENCE_OF.c" />
    1.78 -    <ClCompile Include="..\..\asn.1\constr_SET_OF.c" />
    1.79 -    <ClCompile Include="..\..\asn.1\constr_TYPE.c" />
    1.80 -    <ClCompile Include="..\..\asn.1\der_encoder.c" />
    1.81 -    <ClCompile Include="..\..\asn.1\GroupKeys.c" />
    1.82 -    <ClCompile Include="..\..\asn.1\GroupKeysAndClose.c" />
    1.83 -    <ClCompile Include="..\..\asn.1\GroupTrustThisKey.c" />
    1.84 -    <ClCompile Include="..\..\asn.1\HandshakeAnswer.c" />
    1.85 -    <ClCompile Include="..\..\asn.1\HandshakeRequest.c" />
    1.86 -    <ClCompile Include="..\..\asn.1\Hash.c" />
    1.87 -    <ClCompile Include="..\..\asn.1\Hex.c" />
    1.88 -    <ClCompile Include="..\..\asn.1\Identity.c" />
    1.89 -    <ClCompile Include="..\..\asn.1\IdentityList.c" />
    1.90 -    <ClCompile Include="..\..\asn.1\INTEGER.c" />
    1.91 -    <ClCompile Include="..\..\asn.1\ISO639-1.c" />
    1.92 -    <ClCompile Include="..\..\asn.1\KeySync.c" />
    1.93 -    <ClCompile Include="..\..\asn.1\NativeEnumerated.c" />
    1.94 -    <ClCompile Include="..\..\asn.1\NativeInteger.c" />
    1.95 -    <ClCompile Include="..\..\asn.1\OCTET_STRING.c" />
    1.96 -    <ClCompile Include="..\..\asn.1\pdu_collection.c" />
    1.97 -    <ClCompile Include="..\..\asn.1\per_decoder.c" />
    1.98 -    <ClCompile Include="..\..\asn.1\per_encoder.c" />
    1.99 -    <ClCompile Include="..\..\asn.1\per_opentype.c" />
   1.100 -    <ClCompile Include="..\..\asn.1\per_support.c" />
   1.101 -    <ClCompile Include="..\..\asn.1\PrintableString.c" />
   1.102 -    <ClCompile Include="..\..\asn.1\PString.c" />
   1.103 -    <ClCompile Include="..\..\asn.1\Rollback.c" />
   1.104 -    <ClCompile Include="..\..\asn.1\Sync.c" />
   1.105 -    <ClCompile Include="..\..\asn.1\TID.c" />
   1.106 -    <ClCompile Include="..\..\asn.1\UTF8String.c" />
   1.107 -    <ClCompile Include="..\..\asn.1\Version.c" />
   1.108 -    <ClCompile Include="..\..\asn.1\xer_decoder.c" />
   1.109 -    <ClCompile Include="..\..\asn.1\xer_encoder.c" />
   1.110 -    <ClCompile Include="..\..\asn.1\xer_support.c" />
   1.111 +    <ClCompile Include="..\..\asn.1\*.c" />
   1.112    </ItemGroup>
   1.113    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   1.114    <ImportGroup Label="ExtensionTargets">
     2.1 --- a/build-windows/libpEpasn1/libpEpasn1.vcxproj.filters	Mon Apr 29 12:15:05 2019 +0200
     2.2 +++ b/build-windows/libpEpasn1/libpEpasn1.vcxproj.filters	Mon Apr 29 12:15:53 2019 +0200
     2.3 @@ -174,6 +174,21 @@
     2.4      <ClInclude Include="..\..\asn.1\GroupTrustThisKey.h">
     2.5        <Filter>Header Files</Filter>
     2.6      </ClInclude>
     2.7 +    <ClInclude Include="..\..\asn.1\CommitAcceptFirst.h">
     2.8 +      <Filter>Header Files</Filter>
     2.9 +    </ClInclude>
    2.10 +    <ClInclude Include="..\..\asn.1\CommitAcceptSecond.h">
    2.11 +      <Filter>Header Files</Filter>
    2.12 +    </ClInclude>
    2.13 +    <ClInclude Include="..\..\asn.1\OwnKeys.h">
    2.14 +      <Filter>Header Files</Filter>
    2.15 +    </ClInclude>
    2.16 +    <ClInclude Include="..\..\asn.1\OwnKeysFirst.h">
    2.17 +      <Filter>Header Files</Filter>
    2.18 +    </ClInclude>
    2.19 +    <ClInclude Include="..\..\asn.1\OwnKeysSecond.h">
    2.20 +      <Filter>Header Files</Filter>
    2.21 +    </ClInclude>
    2.22    </ItemGroup>
    2.23    <ItemGroup>
    2.24      <ClCompile Include="..\..\asn.1\asn_codecs_prim.c">
    2.25 @@ -233,9 +248,6 @@
    2.26      <ClCompile Include="..\..\asn.1\GroupKeys.c">
    2.27        <Filter>Source Files</Filter>
    2.28      </ClCompile>
    2.29 -    <ClCompile Include="..\..\asn.1\GroupKeysAndClose.c">
    2.30 -      <Filter>Source Files</Filter>
    2.31 -    </ClCompile>
    2.32      <ClCompile Include="..\..\asn.1\HandshakeAnswer.c">
    2.33        <Filter>Source Files</Filter>
    2.34      </ClCompile>
    2.35 @@ -323,5 +335,20 @@
    2.36      <ClCompile Include="..\..\asn.1\GroupTrustThisKey.c">
    2.37        <Filter>Source Files</Filter>
    2.38      </ClCompile>
    2.39 +    <ClCompile Include="..\..\asn.1\CommitAcceptFirst.c">
    2.40 +      <Filter>Source Files</Filter>
    2.41 +    </ClCompile>
    2.42 +    <ClCompile Include="..\..\asn.1\CommitAcceptSecond.c">
    2.43 +      <Filter>Source Files</Filter>
    2.44 +    </ClCompile>
    2.45 +    <ClCompile Include="..\..\asn.1\OwnKeys.c">
    2.46 +      <Filter>Source Files</Filter>
    2.47 +    </ClCompile>
    2.48 +    <ClCompile Include="..\..\asn.1\OwnKeysFirst.c">
    2.49 +      <Filter>Source Files</Filter>
    2.50 +    </ClCompile>
    2.51 +    <ClCompile Include="..\..\asn.1\OwnKeysSecond.c">
    2.52 +      <Filter>Source Files</Filter>
    2.53 +    </ClCompile>
    2.54    </ItemGroup>
    2.55  </Project>
    2.56 \ No newline at end of file
     3.1 --- a/src/baseprotocol.c	Mon Apr 29 12:15:05 2019 +0200
     3.2 +++ b/src/baseprotocol.c	Mon Apr 29 12:15:53 2019 +0200
     3.3 @@ -9,8 +9,7 @@
     3.4          message *msg,
     3.5          char *payload,
     3.6          size_t size,
     3.7 -        const char *fpr,
     3.8 -        stringlist_t **keys
     3.9 +        const char *fpr
    3.10      )
    3.11  {
    3.12      PEP_STATUS status = PEP_STATUS_OK;
    3.13 @@ -45,30 +44,6 @@
    3.14              goto enomem;
    3.15      }
    3.16  
    3.17 -    if (keys) {
    3.18 -        size_t size = 1;
    3.19 -        for (stringlist_t *sl = *keys; sl && sl->value; sl = sl->next) {
    3.20 -            size += strlen(sl->value);
    3.21 -        }
    3.22 -
    3.23 -        char *_keys = calloc(1, size);
    3.24 -        if (!_keys)
    3.25 -            goto enomem;
    3.26 -
    3.27 -        char *_k = _keys;
    3.28 -        for (stringlist_t *sl = *keys; sl && sl->value; sl = sl->next) {
    3.29 -            strcpy(_k, sl->value);
    3.30 -            _k += strlen(sl->value);
    3.31 -        }
    3.32 -
    3.33 -        bl = bloblist_add(bl, _keys, size, "application/pgp-keys", "keys.asc");
    3.34 -        if (!bl)
    3.35 -            status = PEP_OUT_OF_MEMORY;
    3.36 -
    3.37 -        free_stringlist(*keys);
    3.38 -        *keys = NULL;
    3.39 -    }
    3.40 -
    3.41      return status;
    3.42  
    3.43  enomem:
    3.44 @@ -85,7 +60,6 @@
    3.45          char *payload,
    3.46          size_t size,
    3.47          const char *fpr,
    3.48 -        stringlist_t **keys,
    3.49          message **result
    3.50      )
    3.51  {
    3.52 @@ -127,7 +101,7 @@
    3.53      if (!msg->longmsg)
    3.54          goto enomem;
    3.55  
    3.56 -    status = base_decorate_message(session, msg, payload, size, fpr, keys);
    3.57 +    status = base_decorate_message(session, msg, payload, size, fpr);
    3.58      if (status == PEP_STATUS_OK)
    3.59          *result = msg;
    3.60      return status;
     4.1 --- a/src/baseprotocol.h	Mon Apr 29 12:15:05 2019 +0200
     4.2 +++ b/src/baseprotocol.h	Mon Apr 29 12:15:53 2019 +0200
     4.3 @@ -31,8 +31,7 @@
     4.4          message *msg,
     4.5          char *payload,
     4.6          size_t size,
     4.7 -        const char *fpr,
     4.8 -        stringlist_t **keys
     4.9 +        const char *fpr
    4.10      );
    4.11  
    4.12  
    4.13 @@ -61,7 +60,6 @@
    4.14          char *payload,
    4.15          size_t size,
    4.16          const char *fpr,
    4.17 -        stringlist_t **keys,
    4.18          message **result
    4.19      );
    4.20  
     5.1 --- a/src/message_api.c	Mon Apr 29 12:15:05 2019 +0200
     5.2 +++ b/src/message_api.c	Mon Apr 29 12:15:53 2019 +0200
     5.3 @@ -3019,6 +3019,8 @@
     5.4      }
     5.5      
     5.6      resultid->lang[0] = srcid->lang[0];
     5.7 +    resultid->lang[1] = srcid->lang[1];
     5.8 +    resultid->lang[2] = 0;
     5.9      resultid->me = srcid->me;
    5.10      resultid->flags = srcid->flags;
    5.11  
     6.1 --- a/src/pEpEngine.c	Mon Apr 29 12:15:05 2019 +0200
     6.2 +++ b/src/pEpEngine.c	Mon Apr 29 12:15:53 2019 +0200
     6.3 @@ -4182,7 +4182,7 @@
     6.4              filename_ptr);
     6.5  
     6.6      if (status == PEP_DECRYPT_NO_KEY)
     6.7 -        signal_Sync_event(session, Sync_PR_keysync, CannotDecrypt);
     6.8 +        signal_Sync_event(session, Sync_PR_keysync, CannotDecrypt, NULL);
     6.9  
    6.10      return status;
    6.11  }
    6.12 @@ -4362,7 +4362,7 @@
    6.13      if (identity->fpr)
    6.14          status = set_pgp_keypair(session, identity->fpr);
    6.15  
    6.16 -    signal_Sync_event(session, Sync_PR_keysync, KeyGen);
    6.17 +    signal_Sync_event(session, Sync_PR_keysync, KeyGen, NULL);
    6.18  
    6.19      // add to known keypair DB, as this might not end up being a default
    6.20      return status;
     7.1 --- a/src/pEp_internal.h	Mon Apr 29 12:15:05 2019 +0200
     7.2 +++ b/src/pEp_internal.h	Mon Apr 29 12:15:53 2019 +0200
     7.3 @@ -99,12 +99,12 @@
     7.4  #endif
     7.5  #endif
     7.6  
     7.7 -#ifdef USE_GPG
     7.8 -#include "pgp_gpg_internal.h"
     7.9 +#if defined(USE_SEQUOIA)
    7.10 +#include "pgp_sequoia_internal.h"
    7.11  #elif defined(USE_NETPGP)
    7.12  #include "pgp_netpgp_internal.h"
    7.13 -#elif defined(USE_SEQUOIA)
    7.14 -#include "pgp_sequoia_internal.h"
    7.15 +#elif defined(USE_GPG)
    7.16 +#include "pgp_gpg_internal.h"
    7.17  #endif
    7.18  
    7.19  #include "keymanagement.h"
     8.1 --- a/src/pgp_sequoia.c	Mon Apr 29 12:15:05 2019 +0200
     8.2 +++ b/src/pgp_sequoia.c	Mon Apr 29 12:15:53 2019 +0200
     8.3 @@ -1,6 +1,8 @@
     8.4  // This file is under GNU General Public License 3.0
     8.5  // see LICENSE.txt
     8.6  
     8.7 +#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
     8.8 +
     8.9  #define _GNU_SOURCE 1
    8.10  
    8.11  #include "platform.h"
    8.12 @@ -11,8 +13,6 @@
    8.13  #include <sys/stat.h>
    8.14  #include <sys/types.h>
    8.15  
    8.16 -#include <sqlite3.h>
    8.17 -
    8.18  #include "wrappers.h"
    8.19  
    8.20  #define TRACING 0
    8.21 @@ -77,11 +77,17 @@
    8.22          ERROR_OUT(NULL, PEP_INIT_GPGME_INIT_FAILED, "HOME unset");
    8.23  
    8.24      // Create the DB and initialize it.
    8.25 -    char *path = NULL;
    8.26 -    asprintf(&path, "%s/.pEp_keys.db", home_env);
    8.27 +    size_t path_size = strlen(home_env)+13+1;
    8.28 +    char *path = (char *) calloc(1, path_size);
    8.29 +    assert(path);
    8.30      if (!path)
    8.31          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    8.32  
    8.33 +    int r = snprintf(path, path_size, "%s/.pEp_keys.db", home_env);
    8.34 +    assert(r >= 0 && r < path_size);
    8.35 +    if (r < 0)
    8.36 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
    8.37 +
    8.38      int sqlite_result;
    8.39      sqlite_result = sqlite3_open_v2(path,
    8.40                                      &session->key_db,
    8.41 @@ -290,6 +296,8 @@
    8.42      }
    8.43  }
    8.44  
    8.45 +/* commented out to omit compiler warning about unused function
    8.46 +
    8.47  // Ensures that a fingerprint is in canonical form.  A canonical
    8.48  // fingerprint doesn't contain any white space.
    8.49  //
    8.50 @@ -304,6 +312,8 @@
    8.51      return fpr_canonicalized;
    8.52  }
    8.53  
    8.54 +*/
    8.55 +
    8.56  // Splits an OpenPGP user id into its name and email components.  A
    8.57  // user id looks like:
    8.58  //
    8.59 @@ -804,9 +814,9 @@
    8.60      j = 0;
    8.61      for (i = 0; i < keyids_len; i ++) {
    8.62          pgp_tpk_t tpk = NULL;
    8.63 -        pgp_status_t status
    8.64 +        PEP_STATUS status
    8.65              = tpk_find_by_keyid(session, keyids[i], false, &tpk, NULL);
    8.66 -        if (status == PGP_STATUS_SUCCESS)
    8.67 +        if (status == PEP_STATUS_OK)
    8.68              (*tpks)[j ++] = tpk;
    8.69      }
    8.70      *tpk_len = j;
    8.71 @@ -1114,7 +1124,7 @@
    8.72                                       128 * 1024 * 1024) > 0))
    8.73          ;
    8.74      if (nread < 0)
    8.75 -        ERROR_OUT(err, PGP_STATUS_UNKNOWN_ERROR, "pgp_reader_read");
    8.76 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "pgp_reader_read");
    8.77  
    8.78      // Add a terminating NUL for naive users
    8.79      pgp_writer_write(&err, writer, (const uint8_t *) &""[0], 1);
    8.80 @@ -1500,9 +1510,16 @@
    8.81      assert(identity->fpr == NULL || identity->fpr[0] == 0);
    8.82      assert(identity->username);
    8.83  
    8.84 -    asprintf(&userid, "%s <%s>", identity->username, identity->address);
    8.85 -    if (! userid)
    8.86 -        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "asprintf");
    8.87 +    size_t userid_size = strlen(identity->username)+strlen(identity->address)+3+1;
    8.88 +    userid = (char *) calloc(1, userid_size);
    8.89 +    assert(userid);
    8.90 +    if (!userid)
    8.91 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    8.92 +
    8.93 +    int r = snprintf(userid, userid_size, "%s <%s>", identity->username, identity->address);
    8.94 +    assert(r >= 0 && r < userid_size);
    8.95 +    if (r < 0)
    8.96 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "snprintf");
    8.97  
    8.98      T("(%s)", userid);
    8.99  
   8.100 @@ -1542,24 +1559,35 @@
   8.101      return status;
   8.102  }
   8.103  
   8.104 -PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
   8.105 +#define SQL_DELETE "DELETE FROM keys WHERE primary_key = '%s' ;"
   8.106 +static const char *sql_delete = SQL_DELETE;
   8.107 +static const size_t sql_delete_size = sizeof(SQL_DELETE);
   8.108 +
   8.109 +// FIXME: this is deleting the key from the index but not the key data
   8.110 +
   8.111 +PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
   8.112  {
   8.113 +    assert(session && fpr && fpr[0]);
   8.114 +    if (!(session && fpr && fpr[0]))
   8.115 +        return PEP_ILLEGAL_VALUE;
   8.116  
   8.117 -	return PEP_CANNOT_DELETE_KEY;
   8.118 -/*    
   8.119 -    PEP_STATUS status = PEP_STATUS_OK;
   8.120 -    char *fpr = pgp_fingerprint_canonicalize(fpr_raw);
   8.121 +    size_t sql_size = sql_delete_size + strlen(fpr);
   8.122 +    char *sql = calloc(1, sql_size);
   8.123 +    assert(sql);
   8.124 +    if (!sql)
   8.125 +        return PEP_OUT_OF_MEMORY;
   8.126  
   8.127 -    T("(%s)", fpr);
   8.128 +    int r = snprintf(sql, sql_size, sql_delete, fpr);
   8.129 +    assert(r > 0 && r < sql_size);
   8.130 +    if (r < 0)
   8.131 +        return PEP_UNKNOWN_ERROR;
   8.132  
   8.133 -    // XXX: Can also be used for deleting public keys!!!
   8.134 -    assert(!"implement me");
   8.135 +    int sqlite_result = sqlite3_exec(session->key_db, sql, NULL, NULL, NULL);
   8.136 +    assert(sqlite_result == SQLITE_OK);
   8.137 +    if (sqlite_result != SQLITE_OK)
   8.138 +        return PEP_CANNOT_DELETE_KEY;
   8.139  
   8.140 -    T("(%s) -> %s", fpr, pep_status_to_string(status));
   8.141 -
   8.142 -    free(fpr);
   8.143 -    return status;
   8.144 -*/
   8.145 +    return PEP_STATUS_OK;
   8.146  }
   8.147  
   8.148  // XXX: This needs to handle not only TPKs, but also keyrings and
     9.1 --- a/src/sync_api.c	Mon Apr 29 12:15:05 2019 +0200
     9.2 +++ b/src/sync_api.c	Mon Apr 29 12:15:53 2019 +0200
     9.3 @@ -75,20 +75,19 @@
     9.4              return PEP_ILLEGAL_VALUE;
     9.5      }
     9.6  
     9.7 -    free_identity_list(session->sync_state.common.own_identities);
     9.8 -    session->sync_state.common.own_identities = NULL;
     9.9 +    identity_list *own_identities = NULL;
    9.10  
    9.11      if (identities_sharing && identities_sharing->ident) {
    9.12 -        session->sync_state.common.own_identities = identity_list_dup(identities_sharing);
    9.13 -        if (!session->sync_state.common.own_identities)
    9.14 -            status = PEP_OUT_OF_MEMORY;
    9.15 +        own_identities = identity_list_dup(identities_sharing);
    9.16 +        if (!own_identities)
    9.17 +            return PEP_OUT_OF_MEMORY;
    9.18      }
    9.19      else {
    9.20 -        status = own_identities_retrieve(session, &session->sync_state.common.own_identities);
    9.21 +        status = own_identities_retrieve(session, &own_identities);
    9.22      }
    9.23  
    9.24      if (!status)
    9.25 -        status = signal_Sync_event(session, Sync_PR_keysync, event);
    9.26 +        status = signal_Sync_event(session, Sync_PR_keysync, event, own_identities);
    9.27      return status;
    9.28  }
    9.29  
    10.1 --- a/sync/cond_act_sync.yml2	Mon Apr 29 12:15:05 2019 +0200
    10.2 +++ b/sync/cond_act_sync.yml2	Mon Apr 29 12:15:53 2019 +0200
    10.3 @@ -47,8 +47,8 @@
    10.4  
    10.5  condition sameTransaction
    10.6  ||
    10.7 -    TID_t *t1 = &session->sync_state.keysync.transaction;
    10.8 -    TID_t *t2 = &session->own_sync_state.transaction;
    10.9 +    TID_t *t1 = &session->sync_state.keysync.negotiation;
   10.10 +    TID_t *t2 = &session->own_sync_state.negotiation;
   10.11  
   10.12      *result = t1->size == t2->size && memcmp(t1->buf, t2->buf, t1->size) == 0;
   10.13  ||
   10.14 @@ -117,23 +117,23 @@
   10.15  
   10.16  action openTransaction {
   10.17  ||
   10.18 -    for (int i=0; i<session->sync_state.keysync.transaction.size; ++i) {
   10.19 -        if (session->sync_state.keysync.transaction.buf[i])
   10.20 +    for (int i=0; i<session->sync_state.keysync.negotiation.size; ++i) {
   10.21 +        if (session->sync_state.keysync.negotiation.buf[i])
   10.22              return PEP_STATUS_OK;
   10.23      }
   10.24  ||
   10.25 -    call "new_UUID" with "dst" > &session->sync_state.keysync.transaction
   10.26 +    call "new_UUID" with "dst" > &session->sync_state.keysync.negotiation
   10.27  }
   10.28  
   10.29  action closeTransaction
   10.30  ||
   10.31 -    memset(session->sync_state.keysync.transaction.buf, 0,
   10.32 -            session->sync_state.keysync.transaction.size);
   10.33 +    memset(session->sync_state.keysync.negotiation.buf, 0,
   10.34 +            session->sync_state.keysync.negotiation.size);
   10.35  ||
   10.36  
   10.37  action storeTransaction call "copy_UUID" {
   10.38 -    with "src" > &session->sync_state.keysync.transaction
   10.39 -    with "dst" > &session->own_sync_state.transaction
   10.40 +    with "src" > &session->sync_state.keysync.negotiation
   10.41 +    with "dst" > &session->own_sync_state.negotiation
   10.42  }
   10.43  
   10.44  function "show_handshake" {
   10.45 @@ -323,16 +323,6 @@
   10.46      free_identity_list(il);
   10.47  ||
   10.48  
   10.49 -action storeThisKey
   10.50 -||
   10.51 -    free(session->sync_state.common.signature_fpr);
   10.52 -    session->sync_state.common.signature_fpr =
   10.53 -            strndup((char *)session->sync_state.keysync.key.buf, session->sync_state.keysync.key.size);
   10.54 -    assert(session->sync_state.common.signature_fpr);
   10.55 -    if (!session->sync_state.common.signature_fpr)
   10.56 -        return PEP_OUT_OF_MEMORY;
   10.57 -||
   10.58 -
   10.59  action trustThisKey
   10.60  ||
   10.61      assert(session->sync_state.common.from && session->sync_state.common.signature_fpr);
    11.1 --- a/sync/gen_messages.ysl2	Mon Apr 29 12:15:05 2019 +0200
    11.2 +++ b/sync/gen_messages.ysl2	Mon Apr 29 12:15:53 2019 +0200
    11.3 @@ -22,7 +22,7 @@
    11.4      -- This file is under BSD License 2.0
    11.5  
    11.6      -- «@name» protocol for p≡p
    11.7 -    -- Copyright (c) 2016-2018 p≡p foundation
    11.8 +    -- Copyleft 2016-2019 by p≡p foundation
    11.9  
   11.10      -- Written by Volker Birk
   11.11  
    12.1 --- a/sync/gen_statemachine.ysl2	Mon Apr 29 12:15:05 2019 +0200
    12.2 +++ b/sync/gen_statemachine.ysl2	Mon Apr 29 12:15:53 2019 +0200
    12.3 @@ -39,6 +39,9 @@
    12.4              // transport data
    12.5              pEp_identity *from;
    12.6              char *signature_fpr;
    12.7 +
    12.8 +            // identities to sync
    12.9 +            identity_list *own_identities;
   12.10          } «@name»_event_t;
   12.11  
   12.12   
   12.13 @@ -114,6 +117,7 @@
   12.14          void free_«@name»_event(«@name»_event_t *ev)
   12.15          {
   12.16              if (ev) {
   12.17 +                free_identity_list(ev->own_identities);
   12.18                  free_«@name»_message(ev->msg);
   12.19                  free_identity(ev->from);
   12.20                  free(ev->signature_fpr);
   12.21 @@ -190,11 +194,13 @@
   12.22              // API being used by the engine internally
   12.23  
   12.24              // call this if you need to signal an external event
   12.25 +            // caveat: the ownership of own_identities goes to the callee
   12.26  
   12.27              PEP_STATUS signal_«@name»_event(
   12.28                      PEP_SESSION session, 
   12.29                      «@name»_PR fsm,
   12.30 -                    int event
   12.31 +                    int event,
   12.32 +                    identity_list *own_identities
   12.33                  );
   12.34              
   12.35              // call this if you are a transport and are receiving
   12.36 @@ -268,7 +274,8 @@
   12.37              PEP_STATUS signal_«@name»_event(
   12.38                      PEP_SESSION session, 
   12.39                      «@name»_PR fsm,
   12.40 -                    int event
   12.41 +                    int event,
   12.42 +                    identity_list *own_identities
   12.43                  )
   12.44              {
   12.45                  «@name»_t *msg = NULL;
   12.46 @@ -301,6 +308,8 @@
   12.47                      goto the_end;
   12.48                  }
   12.49  
   12.50 +                ev->own_identities = own_identities;
   12.51 +
   12.52                  int result = session->inject_«yml:lcase(@name)»_event(ev,
   12.53                          session->«yml:lcase(@name)»_management);
   12.54                  if (result) {
   12.55 @@ -406,6 +415,8 @@
   12.56                  char *data = NULL;
   12.57                  message *m = NULL;
   12.58                  identity_list *channels = NULL;
   12.59 +                char *key_data = NULL;
   12.60 +                size_t key_data_size = 0;
   12.61  
   12.62                  status = update_«@name»_message(session, msg);
   12.63                  if (status)
   12.64 @@ -497,7 +508,6 @@
   12.65                                      _data,
   12.66                                      size,
   12.67                                      li->ident->fpr,
   12.68 -                                    NULL,
   12.69                                      &_m
   12.70                                  );
   12.71                              if (status) {
   12.72 @@ -552,7 +562,6 @@
   12.73                                      _data,
   12.74                                      size,
   12.75                                      NULL,
   12.76 -                                    &session->«yml:lcase(@name)»_state.common.own_keys,
   12.77                                      &_m
   12.78                                  );
   12.79                              if (status) {
   12.80 @@ -560,6 +569,83 @@
   12.81                                  goto the_end;
   12.82                              }
   12.83  
   12.84 +                            // export secret keys into memory
   12.85 +
   12.86 +                            key_data = strdup("");
   12.87 +                            assert(key_data);
   12.88 +                            if (!key_data) {
   12.89 +                                free(_data);
   12.90 +                                free_message(_m);
   12.91 +                                status = PEP_OUT_OF_MEMORY;
   12.92 +                                goto the_end;
   12.93 +                            }
   12.94 +                            key_data_size = 1;
   12.95 +
   12.96 +                            for (stringlist_t *sl = session->«yml:lcase(@name)»_state.common.own_keys;
   12.97 +                                    sl && sl->value ; sl = sl->next)
   12.98 +                            {
   12.99 +                                char *_key_data = NULL;
  12.100 +                                size_t _size = 0;
  12.101 +                                status = export_secret_key(session, sl->value, &_key_data, &_size);
  12.102 +                                if (status && status != PEP_KEY_NOT_FOUND) {
  12.103 +                                    free(_data);
  12.104 +                                    free_message(_m);
  12.105 +                                    goto the_end;
  12.106 +                                }
  12.107 +
  12.108 +                                if (status != PEP_KEY_NOT_FOUND) {
  12.109 +                                    assert(_key_data && _size);
  12.110 +                                    char *n = realloc(key_data, key_data_size + _size);
  12.111 +                                    if (!n) {
  12.112 +                                        free(_data);
  12.113 +                                        free_message(_m);
  12.114 +                                        status = PEP_OUT_OF_MEMORY;
  12.115 +                                        goto the_end;
  12.116 +                                    }
  12.117 +                                    key_data = n;
  12.118 +                                    key_data_size += _size;
  12.119 +                                    strlcat(key_data, _key_data, key_data_size);
  12.120 +                                    free(_key_data);
  12.121 +                                    _key_data = NULL;
  12.122 +                                }
  12.123 +                                status = export_key(session, sl->value, &_key_data, &_size);
  12.124 +                                if (status && status != PEP_KEY_NOT_FOUND) {
  12.125 +                                    free(_data);
  12.126 +                                    free_message(_m);
  12.127 +                                    goto the_end;
  12.128 +                                }
  12.129 +
  12.130 +                                if (status != PEP_KEY_NOT_FOUND) {
  12.131 +                                    assert(_key_data && _size);
  12.132 +                                    char *n = realloc(key_data, key_data_size + _size);
  12.133 +                                    if (!n) {
  12.134 +                                        free(_data);
  12.135 +                                        free_message(_m);
  12.136 +                                        status = PEP_OUT_OF_MEMORY;
  12.137 +                                        goto the_end;
  12.138 +                                    }
  12.139 +                                    key_data = n;
  12.140 +                                    key_data_size += _size;
  12.141 +                                    strlcat(key_data, _key_data, key_data_size);
  12.142 +                                    free(_key_data);
  12.143 +                                    _key_data = NULL;
  12.144 +                                }
  12.145 +                            }
  12.146 +
  12.147 +                            // add secret key data as attachment
  12.148 +
  12.149 +                            bloblist_t *bl = bloblist_add(_m->attachments, key_data, key_data_size,
  12.150 +                                    "application/octet-stream", "file://own.key");
  12.151 +                            if (!bl) {
  12.152 +                                free(_data);
  12.153 +                                free_message(_m);
  12.154 +                                status = PEP_OUT_OF_MEMORY;
  12.155 +                                goto the_end;
  12.156 +                            }
  12.157 +                            key_data = NULL;
  12.158 +
  12.159 +                            // add fpr of key of comm partner
  12.160 +
  12.161                              extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
  12.162                              if (extra) {
  12.163                                  status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
  12.164 @@ -583,7 +669,6 @@
  12.165                                      _data,
  12.166                                      size,
  12.167                                      NULL,
  12.168 -                                    NULL,
  12.169                                      &_m
  12.170                                  );
  12.171                              if (status) {
  12.172 @@ -620,6 +705,7 @@
  12.173                  free_identity_list(channels);
  12.174                  free_message(m);
  12.175                  free(data);
  12.176 +                free(key_data);
  12.177                  free_«@name»_message(msg);
  12.178                  return status;
  12.179              }
  12.180 @@ -661,22 +747,23 @@
  12.181                  // update transport data
  12.182  
  12.183                  if (ev->from) {
  12.184 -                    free_identity(session->sync_state.common.from);
  12.185 -                    session->sync_state.common.from = identity_dup(ev->from);
  12.186 -                    if (!session->sync_state.common.from) {
  12.187 -                        status = PEP_OUT_OF_MEMORY;
  12.188 -                        goto the_end;
  12.189 -                    }
  12.190 +                    free_identity(session->«yml:lcase(@name)»_state.common.from);
  12.191 +                    session->«yml:lcase(@name)»_state.common.from = ev->from;
  12.192 +                    ev->from = NULL;
  12.193                  }
  12.194  
  12.195                  if (ev->signature_fpr) {
  12.196 -                    free(session->sync_state.common.signature_fpr);
  12.197 -                    session->sync_state.common.signature_fpr = strdup(ev->signature_fpr);
  12.198 -                    assert(session->sync_state.common.signature_fpr);
  12.199 -                    if (!session->sync_state.common.signature_fpr) {
  12.200 -                        status = PEP_OUT_OF_MEMORY;
  12.201 -                        goto the_end;
  12.202 -                    }
  12.203 +                    free(session->«yml:lcase(@name)»_state.common.signature_fpr);
  12.204 +                    session->«yml:lcase(@name)»_state.common.signature_fpr = ev->signature_fpr;
  12.205 +                    ev->signature_fpr = NULL;
  12.206 +                }
  12.207 +
  12.208 +                // update own identities
  12.209 +
  12.210 +                if (ev->own_identities && ev->own_identities->ident) {
  12.211 +                    free_identity_list(session->«yml:lcase(@name)»_state.common.own_identities);
  12.212 +                    session->«yml:lcase(@name)»_state.common.own_identities = ev->own_identities;
  12.213 +                    ev->own_identities = NULL;
  12.214                  }
  12.215  
  12.216                  status = «@name»_driver(session, fsm, event);
    13.1 --- a/sync/sync.fsm	Mon Apr 29 12:15:05 2019 +0200
    13.2 +++ b/sync/sync.fsm	Mon Apr 29 12:15:53 2019 +0200
    13.3 @@ -10,7 +10,7 @@
    13.4  protocol Sync 1 {
    13.5      // all messages have a timestamp, time out and are removed after timeout
    13.6  
    13.7 -    fsm KeySync 1 {
    13.8 +    fsm KeySync 1, threshold=30 {
    13.9          version 1, 2;
   13.10  
   13.11          state InitState {
   13.12 @@ -45,32 +45,32 @@
   13.13                      }
   13.14                      else /* we are second */ {
   13.15                          do storeChallenge; // partner's challenge
   13.16 -                        do openTransaction; // NOP if transaction already open
   13.17 +                        do openTransaction; // NOP if negotiation already open
   13.18                          do storeTransaction;
   13.19                          do tellWeAreNotGrouped;
   13.20 -                        // second is sending HandshakeRequest
   13.21 -                        send HandshakeRequest;
   13.22 +                        // second is sending NegotiationRequest
   13.23 +                        send NegotiationRequest;
   13.24                      }
   13.25                  }
   13.26              }
   13.27  
   13.28 -            on HandshakeRequest if challengeAccepted {
   13.29 +            on NegotiationRequest if challengeAccepted {
   13.30                  if sameTransaction {
   13.31                      // this is our own handshake request; ignore
   13.32                  }
   13.33                  else {
   13.34 -                    // first is receiving HandshakeRequest
   13.35 +                    // first is receiving NegotiationRequest
   13.36                      do storeTransaction;
   13.37 -                    // first is sending HandshakeAnswer
   13.38 -                    send HandshakeAnswer;
   13.39 +                    // first is sending NegotiationOpen
   13.40 +                    send NegotiationOpen;
   13.41                      if partnerIsGrouped
   13.42                          go HandshakingWithGroup;
   13.43                      go HandshakingNewFirst;
   13.44                  }
   13.45              }
   13.46  
   13.47 -            on HandshakeAnswer if sameTransaction {
   13.48 -                // second is receiving HandshakeAnswer
   13.49 +            on NegotiationOpen if sameTransaction {
   13.50 +                // second is receiving NegotiationOpen
   13.51                  go HandshakingNewSecond;
   13.52              }
   13.53          }
   13.54 @@ -104,12 +104,12 @@
   13.55              // Accept means init Phase1Commit
   13.56              on Accept {
   13.57                  do trustThisKey;
   13.58 -                send CommitAccept;
   13.59 +                send CommitAcceptFirst;
   13.60                  go HandshakingNewPhase1First;
   13.61              }
   13.62  
   13.63              // got a CommitAccept from second
   13.64 -            on CommitAcceptForGroup if sameTransaction
   13.65 +            on CommitAcceptSecond if sameTransaction
   13.66                  go HandshakingNewPhase2First;
   13.67          }
   13.68  
   13.69 @@ -142,12 +142,12 @@
   13.70              // Accept means init Phase1Commit
   13.71              on Accept {
   13.72                  do trustThisKey;
   13.73 -                send CommitAcceptForGroup;
   13.74 +                send CommitAcceptSecond;
   13.75                  go HandshakingNewPhase1Second;
   13.76              }
   13.77  
   13.78              // got a CommitAccept from first
   13.79 -            on CommitAccept if sameTransaction
   13.80 +            on CommitAcceptFirst if sameTransaction
   13.81                  go HandshakingNewPhase2Second;
   13.82          }
   13.83  
   13.84 @@ -163,8 +163,9 @@
   13.85                  go End;
   13.86              }
   13.87  
   13.88 -            on CommitAcceptForGroup if sameTransaction
   13.89 +            on CommitAcceptSecond if sameTransaction {
   13.90                  go NewGroupFirst;
   13.91 +            }
   13.92          }
   13.93  
   13.94          state HandshakingNewPhase1Second {
   13.95 @@ -179,8 +180,9 @@
   13.96                  go End;
   13.97              }
   13.98  
   13.99 -            on CommitAccept if sameTransaction
  13.100 +            on CommitAcceptFirst if sameTransaction {
  13.101                  go NewGroupSecond;
  13.102 +            }
  13.103          }
  13.104  
  13.105          state HandshakingNewPhase2First {
  13.106 @@ -196,6 +198,7 @@
  13.107              }
  13.108  
  13.109              on Accept {
  13.110 +                send CommitAcceptFirst;
  13.111                  do trustThisKey;
  13.112                  go NewGroupFirst;
  13.113              }
  13.114 @@ -214,6 +217,7 @@
  13.115              }
  13.116  
  13.117              on Accept {
  13.118 +                send CommitAcceptSecond;
  13.119                  do trustThisKey;
  13.120                  go NewGroupSecond;
  13.121              }
  13.122 @@ -222,10 +226,10 @@
  13.123          state NewGroupFirst {
  13.124              on Init {
  13.125                  do prepareOwnKeys;
  13.126 -                send GroupKeys; // we're not grouped yet, this is our own keys
  13.127 +                send OwnKeysFirst; // we're not grouped yet, this is our own keys
  13.128              }
  13.129  
  13.130 -            on GroupKeysAndClose if sameTransaction {
  13.131 +            on OwnKeysSecond {
  13.132                  do saveGroupKeys;
  13.133  
  13.134                  if keyElectionWon
  13.135 @@ -240,10 +244,10 @@
  13.136          state NewGroupSecond {
  13.137              on Init {
  13.138                  do prepareOwnKeys;
  13.139 -                send GroupKeysAndClose; // we're not grouped yet, this is our own keys
  13.140 +                send OwnKeysSecond; // we're not grouped yet, this is our own keys
  13.141              }
  13.142  
  13.143 -            on GroupKeys {
  13.144 +            on OwnKeysFirst {
  13.145                  do saveGroupKeys;
  13.146  
  13.147                  if keyElectionWon
  13.148 @@ -264,27 +268,25 @@
  13.149              on GroupKeys
  13.150                  do saveGroupKeys;
  13.151  
  13.152 -            on KeyGen
  13.153 +            on KeyGen {
  13.154 +                do prepareOwnKeys;
  13.155                  send GroupKeys;
  13.156 +            }
  13.157  
  13.158              on Beacon {
  13.159                  do storeChallenge;
  13.160                  do openTransaction;
  13.161                  do storeTransaction;
  13.162                  do tellWeAreGrouped;
  13.163 -                send HandshakeRequest;
  13.164 +                send NegotiationRequest;
  13.165              }
  13.166  
  13.167 -            on HandshakeAnswer if sameTransaction
  13.168 +            on NegotiationOpen if sameTransaction
  13.169                  go HandshakingGrouped;
  13.170  
  13.171              on GroupTrustThisKey {
  13.172 -                do storeThisKey;
  13.173                  do trustThisKey;
  13.174              }
  13.175 -
  13.176 -            on GroupKeysAndClose
  13.177 -                do showDeviceAdded;
  13.178          }
  13.179  
  13.180          // sole device handshaking with group
  13.181 @@ -333,8 +335,9 @@
  13.182                  go End;
  13.183              }
  13.184  
  13.185 -            on CommitAcceptForGroup if sameTransaction
  13.186 +            on CommitAcceptForGroup if sameTransaction {
  13.187                  go JoinGroup;
  13.188 +            }
  13.189          }
  13.190  
  13.191          state HandshakingJoinPhase2 {
  13.192 @@ -356,10 +359,12 @@
  13.193          }
  13.194  
  13.195          state JoinGroup {
  13.196 -            on Init
  13.197 +            on Init {
  13.198 +                do prepareOwnKeys;
  13.199                  send GroupKeys;
  13.200 +            }
  13.201  
  13.202 -            on GroupKeysAndClose {
  13.203 +            on GroupKeys if sameTransaction {
  13.204                  do saveGroupKeys;
  13.205                  do receivedKeysAreGroupKeys;
  13.206                  do showDeviceAdded;
  13.207 @@ -402,7 +407,6 @@
  13.208  
  13.209              on GroupTrustThisKey {
  13.210                  do hideHandshakeDialog;
  13.211 -                do storeThisKey;
  13.212                  do trustThisKey;
  13.213              }
  13.214  
  13.215 @@ -426,12 +430,11 @@
  13.216                  go Grouped;
  13.217  
  13.218              on CommitAccept if sameTransaction {
  13.219 -                send GroupKeysAndClose;
  13.220 +                send GroupKeys;
  13.221                  go Grouped;
  13.222              }
  13.223  
  13.224              on GroupTrustThisKey {
  13.225 -                do storeThisKey;
  13.226                  do trustThisKey;
  13.227              }
  13.228  
  13.229 @@ -459,12 +462,11 @@
  13.230              on Accept {
  13.231                  do trustThisKey;
  13.232                  send GroupTrustThisKey;
  13.233 -                send GroupKeysAndClose;
  13.234 +                send GroupKeys;
  13.235                  go Grouped;
  13.236              }
  13.237  
  13.238              on GroupTrustThisKey {
  13.239 -                do storeThisKey;
  13.240                  do trustThisKey;
  13.241              }
  13.242  
  13.243 @@ -491,47 +493,61 @@
  13.244              auto Version version;
  13.245          }
  13.246  
  13.247 -        message HandshakeRequest 3, security=untrusted {
  13.248 +        message NegotiationRequest 3, security=untrusted {
  13.249              field TID challenge;
  13.250              auto Version version;
  13.251 -            field TID transaction;
  13.252 +            field TID negotiation;
  13.253              field bool is_group;
  13.254          }
  13.255  
  13.256 -        message HandshakeAnswer 4, security=untrusted {
  13.257 +        message NegotiationOpen 4, security=untrusted {
  13.258              auto Version version;
  13.259 -            field TID transaction;
  13.260 +            field TID negotiation;
  13.261          }
  13.262  
  13.263          message Rollback 5, security=untrusted {
  13.264 -            field TID transaction;
  13.265 +            field TID negotiation;
  13.266          }
  13.267  
  13.268          message CommitReject 6, security=untrusted {
  13.269 -            field TID transaction;
  13.270 +            field TID negotiation;
  13.271          }
  13.272  
  13.273 -        message CommitAccept 7, security=untrusted {
  13.274 -            field TID transaction;
  13.275 +        message CommitAcceptFirst 7, security=untrusted {
  13.276 +            field TID negotiation;
  13.277          }
  13.278  
  13.279 -        message CommitAcceptForGroup 8, security=untrusted {
  13.280 -            field TID transaction;
  13.281 +        message CommitAcceptSecond 8, security=untrusted {
  13.282 +            field TID negotiation;
  13.283 +        }
  13.284 +
  13.285 +        message CommitAccept 9, security=untrusted {
  13.286 +            field TID negotiation;
  13.287 +        }
  13.288 +
  13.289 +        message CommitAcceptForGroup 10, security=untrusted {
  13.290 +            field TID negotiation;
  13.291          }
  13.292  
  13.293          // default: security=trusted only
  13.294 -        message GroupTrustThisKey 9 {
  13.295 +        message GroupTrustThisKey 11 {
  13.296              field Hash key;
  13.297          }
  13.298  
  13.299          // security=attach_own_keys implies security=trusted
  13.300 -        message GroupKeysAndClose 10, security=attach_own_keys {
  13.301 -            field TID transaction;
  13.302 +        message GroupKeys 12, security=attach_own_keys {
  13.303              field IdentityList ownIdentities;
  13.304          }
  13.305  
  13.306 -        // security=attach_own_keys implies security=trusted
  13.307 -        message GroupKeys 11, security=attach_own_keys {
  13.308 +        message OwnKeys 13, security=attach_own_keys {
  13.309 +            field IdentityList ownIdentities;
  13.310 +        }
  13.311 +
  13.312 +        message OwnKeysFirst 14, security=attach_own_keys {
  13.313 +            field IdentityList ownIdentities;
  13.314 +        }
  13.315 +
  13.316 +        message OwnKeysSecond 15, security=attach_own_keys {
  13.317              field IdentityList ownIdentities;
  13.318          }
  13.319      }
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/sync/sync_protocol.md	Mon Apr 29 12:15:53 2019 +0200
    14.3 @@ -0,0 +1,70 @@
    14.4 +# p≡p Sync protocol
    14.5 +
    14.6 +## Protocol Stack
    14.7 +
    14.8 +Key Sync | Trust Sync | Contact Sync | Task Sync
    14.9 +- | - | - | -
   14.10 +Sync
   14.11 +Baseprotocol
   14.12 +Transport
   14.13 +
   14.14 +## Forming a Device Group with Key Sync
   14.15 +
   14.16 +### Sender
   14.17 +
   14.18 +A Sender is the Person sending a message. In case of M2M it is the Operating
   14.19 +Entity of the Device sending.
   14.20 +
   14.21 +### Device
   14.22 +
   14.23 +A Device is an entitiy, which is sending representative of a Sender.
   14.24 +
   14.25 +### State Sole
   14.26 +
   14.27 +A Device is in state Sole when it is not member of a Device group and when it
   14.28 +is not part of a Negotiation.
   14.29 +
   14.30 +### State Grouped
   14.31 +
   14.32 +A Device is in state Grouped when it is member of a Device group and when it is
   14.33 +not part of a Negotiation.
   14.34 +
   14.35 +## Negotiation as a Transaction
   14.36 +
   14.37 +### TID
   14.38 +
   14.39 +A TID (transaction ID) is a UUID version 4 variant 1.
   14.40 +
   14.41 +### Challenge
   14.42 +
   14.43 +The Challenge is identified by a TID. The Challenge is being set by each Beacon
   14.44 +and must be repeated in a corresponding Negotiation Request. The Challenge has
   14.45 +two functions:
   14.46 +
   14.47 +1. The Challenge makes it possible to filter out own Beacons
   14.48 +1. The Challenge makes it necessary to be able to read the communication
   14.49 +   channel (usually an Inbox), otherwise Beacons cannot be answered
   14.50 +
   14.51 +### Negotiation
   14.52 +
   14.53 +A Negotiation is a Transaction identified by a TID.
   14.54 +
   14.55 +## Roles and Keys
   14.56 +
   14.57 +### Sender signing
   14.58 +
   14.59 +The key with which the Sender of the message is signing. In case of trusted
   14.60 +messages this is signalled within the encrypted message. This is signalled by
   14.61 +by opt_field pEp-sender-sign, which is not reflected to the outer message.
   14.62 +
   14.63 +Transports can opt to use HMAC or OMAC instead of digital signatures.
   14.64 +
   14.65 +### Transport signing
   14.66 +
   14.67 +Keys with which others and not the Sender are signing a message.
   14.68 +
   14.69 +### Sender Group key
   14.70 +
   14.71 +A Sender Group Key is a Sender's signing key, which is used to update the
   14.72 +Device Group information. If it is reset the Device Groups breaks.
   14.73 +
    15.1 --- a/sync/sync_protocol.txt	Mon Apr 29 12:15:05 2019 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,39 +0,0 @@
    15.4 -p≡p Sync protocol
    15.5 -=================
    15.6 -
    15.7 -1. Protocol Stack
    15.8 ------------------
    15.9 -
   15.10 -Trust Sync | Contact Sync | Task Sync
   15.11 -Sync | Key Sync
   15.12 -Baseprotocol
   15.13 -Transport
   15.14 -
   15.15 -1. Device View
   15.16 ---------------
   15.17 -
   15.18 -1.1 State Sole
   15.19 -
   15.20 -A Device is in state Sole when it is not member of a Device group and when it
   15.21 -is not part of a Negotiation.
   15.22 -
   15.23 -1.1 State Grouped
   15.24 -
   15.25 -A Device is in state Grouped when it is member of a Device group and when it is
   15.26 -not part of a Negotiation.
   15.27 -
   15.28 -1.1 State Handshaking
   15.29 -
   15.30 -A Device is in state Handshaking when it is triggered by receiving a Beacon.
   15.31 -
   15.32 -1.1 State SentCommit
   15.33 -
   15.34 -1.1 State ReceivedCommit
   15.35 -
   15.36 -1. Transaction View for Negotiation
   15.37 ------------------------------------
   15.38 -
   15.39 -A Negotiation is identified by the FPR of the Key of the Identity, which is
   15.40 -used for transport. 
   15.41 -
   15.42 -
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/sync/sync_ux.md	Mon Apr 29 12:15:53 2019 +0200
    16.3 @@ -0,0 +1,94 @@
    16.4 +# p≡p Sync UX
    16.5 +
    16.6 +Sync is a protocol to form one device group. It first is driving a
    16.7 +transaction named the Negotiation. There are two situations Sync can be
    16.8 +in:
    16.9 +
   16.10 +1. either there is no device group yet
   16.11 +2. or there is already a device group
   16.12 +
   16.13 +## Case 1):
   16.14 +
   16.15 +In case 1) we have two devices in the state Sole. When the user
   16.16 +configures the first device, nothing happens. When the user configures
   16.17 +the second device, it will detect that there is another device being in
   16.18 +state Sole.
   16.19 +
   16.20 +The two devices detect each other. Both are showing a dialog asking the
   16.21 +user: “There is another device detected. Shell we form a device group?”
   16.22 +
   16.23 +There are three possible answers:
   16.24 +
   16.25 +1. Accept
   16.26 +1. Reject
   16.27 +1. Cancel
   16.28 +
   16.29 +If one of the devices gets a Cancel, then the device group is NOT
   16.30 +formed. Sync remains enabled on both devices. This is corresponding with
   16.31 +a ROLLBACK of the Negotiation.
   16.32 +
   16.33 +If one of the devices gets a Reject, then the device group is NOT
   16.34 +formed. Sync then is disabled on both devices. This is corresponding
   16.35 +with a COMMIT of the Negotiation with the result REJECT.
   16.36 +
   16.37 +If both devices get an Accept, then the device group is formed. Sync is
   16.38 +then enabled on both devices. This is corresponding with a two-phase
   16.39 +COMMIT of the Negotiation with the result ACCEPT.
   16.40 +
   16.41 +## Case 2):
   16.42 +
   16.43 +In case 2) we have at least two devices forming a device group already
   16.44 +(named “old devices”), being in state Grouped. And we have one device,
   16.45 +which is not yet in a device group (named “new device”), being in state
   16.46 +Sole.
   16.47 +
   16.48 +The new device and the old devices detect that there is a new device,
   16.49 +which could join the existing device group. The new device is showing
   16.50 +a dialog with “There is already a device group. Shell this device join?”
   16.51 +Possible answers are Join/Accept, Reject and Cancel. The old devices are
   16.52 +ALL showing a dialog with “A new device is detected. Shell we accept
   16.53 +the new device as new member in our device group?” Possible answers are
   16.54 +Accept, Reject and Cancel.
   16.55 +
   16.56 +If one of the devices gets a Cancel, then the new device is NOT added to
   16.57 +the device group. Sync remains enabled on all devices. This is
   16.58 +corresponding with a ROLLBACK of the Negotiation.
   16.59 +
   16.60 +If one of the devices gets a Reject, then the new device is NOT added to
   16.61 +the device group. Sync remains enabled on the old devices, but gets
   16.62 +disabled on the new device. This is corresponding with a COMMIT of the
   16.63 +Negotiation with the result REJECT.
   16.64 +
   16.65 +Only if the new device gets an Accept and at least one of the old
   16.66 +devices gets an Accept, then the new device is added to the device group.
   16.67 +Sync then remains enabled on the old devices, and gets enabled on the
   16.68 +new device. This is corresponding with a COMMIT of the Negotiation with
   16.69 +the result ACCEPT.
   16.70 +
   16.71 +Key sync is starting while Sync is taking place. The Sync dialog is a
   16.72 +Trustwords dialog offering Trustwords to check for the user. User's
   16.73 +decision is not only based on if she/he wants to have a device group in
   16.74 +case 1) – or – if she/he wants to add a new device to an existing device
   16.75 +group in case 2), but also on the question, if the Trustwords on the
   16.76 +two handled devices (either the two Sole ones or the new one and one of
   16.77 +the old ones) are identical.
   16.78 +
   16.79 +Because there is a Trustwords check, from then on the connection is
   16.80 +becoming green, and secret keys will be sent and shared on all devices
   16.81 +being member of the same device group.
   16.82 +
   16.83 +When Sync is switched off on a device, then it leaves the device group
   16.84 +it is in. A Key reset is needed then on the remaining devices, dealing
   16.85 +out new group keys for all own identities.
   16.86 +
   16.87 +Sync can be switched on in two ways:
   16.88 +
   16.89 +1. Switched on for all (default in p≡p apps)
   16.90 +2. Switched on only for a list of accounts (reached by switching it off
   16.91 +   first)
   16.92 +
   16.93 +If Sync is enabled in 1) then adding a new account will have Sync for
   16.94 +this account, too, implicitely.
   16.95 +
   16.96 +If Sync is enabled in 2) then adding a new account will have Sync
   16.97 +switched off for this account by default.
    17.1 --- a/sync/sync_ux.txt	Mon Apr 29 12:15:05 2019 +0200
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,96 +0,0 @@
    17.4 -p≡p Sync UX
    17.5 -===========
    17.6 -
    17.7 -Sync is a protocol to form one device group. It first is driving a
    17.8 -transaction named the Negotiation. There are two situations Sync can be
    17.9 -in:
   17.10 -
   17.11 -1) either there is no device group yet
   17.12 -2) or there is already a device group
   17.13 -
   17.14 -Case 1):
   17.15 ---------
   17.16 -
   17.17 -In case 1) we have two devices in the state Sole. When the user
   17.18 -configures the first device, nothing happens. When the user configures
   17.19 -the second device, it will detect that there is another device being in
   17.20 -state Sole.
   17.21 -
   17.22 -The two devices detect each other. Both are showing a dialog asking the
   17.23 -user: “There is another device detected. Shell we form a device group?”
   17.24 -
   17.25 -There are three possible answers:
   17.26 -
   17.27 -a) Accept
   17.28 -b) Reject
   17.29 -c) Cancel
   17.30 -
   17.31 -If one of the devices gets a Cancel, then the device group is NOT
   17.32 -formed. Sync remains enabled on both devices. This is corresponding with
   17.33 -a ROLLBACK of the Negotiation.
   17.34 -
   17.35 -If one of the devices gets a Reject, then the device group is NOT
   17.36 -formed. Sync then is disabled on both devices. This is corresponding
   17.37 -with a COMMIT of the Negotiation with the result REJECT.
   17.38 -
   17.39 -If both devices get an Accept, then the device group is formed. Sync is
   17.40 -then enabled on both devices. This is corresponding with a two-phase
   17.41 -COMMIT of the Negotiation with the result ACCEPT.
   17.42 -
   17.43 -Case 2):
   17.44 -
   17.45 -In case 2) we have at least two devices forming a device group already
   17.46 -(named “old devices”), being in state Grouped. And we have one device,
   17.47 -which is not yet in a device group (named “new device”), being in state
   17.48 -Sole.
   17.49 -
   17.50 -The new device and the old devices detect that there is a new device,
   17.51 -which could join the existing device group. The new device is showing
   17.52 -a dialog with “There is already a device group. Shell this device join?”
   17.53 -Possible answers are Join/Accept, Reject and Cancel. The old devices are
   17.54 -ALL showing a dialog with “A new device is detected. Shell we accept
   17.55 -the new device as new member in our device group?” Possible answers are
   17.56 -Accept, Reject and Cancel.
   17.57 -
   17.58 -If one of the devices gets a Cancel, then the new device is NOT added to
   17.59 -the device group. Sync remains enabled on all devices. This is
   17.60 -corresponding with a ROLLBACK of the Negotiation.
   17.61 -
   17.62 -If one of the devices gets a Reject, then the new device is NOT added to
   17.63 -the device group. Sync remains enabled on the old devices, but gets
   17.64 -disabled on the new device. This is corresponding with a COMMIT of the
   17.65 -Negotiation with the result REJECT.
   17.66 -
   17.67 -Only if the new device gets an Accept and at least one of the old
   17.68 -devices gets an Accept, then the new device is added to the device group.
   17.69 -Sync then remains enabled on the old devices, and gets enabled on the
   17.70 -new device. This is corresponding with a COMMIT of the Negotiation with
   17.71 -the result ACCEPT.
   17.72 -
   17.73 -Key sync is starting while Sync is taking place. The Sync dialog is a
   17.74 -Trustwords dialog offering Trustwords to check for the user. User's
   17.75 -decision is not only based on if she/he wants to have a device group in
   17.76 -case 1) – or – if she/he wants to add a new device to an existing device
   17.77 -group in case 2), but also on the question, if the Trustwords on the
   17.78 -two handled devices (either the two Sole ones or the new one and one of
   17.79 -the old ones) are identical.
   17.80 -
   17.81 -Because there is a Trustwords check, from then on the connection is
   17.82 -becoming green, and secret keys will be sent and shared on all devices
   17.83 -being member of the same device group.
   17.84 -
   17.85 -When Sync is switched off on a device, then it leaves the device group
   17.86 -it is in. A Key reset is needed then on the remaining devices, dealing
   17.87 -out new group keys for all own identities.
   17.88 -
   17.89 -Sync can be switched on in two ways:
   17.90 -
   17.91 -1) Switched on for all (default in p≡p apps)
   17.92 -2) Switched on only for a list of accounts (reached by switching it off
   17.93 -   first)
   17.94 -
   17.95 -If Sync is enabled in 1) then adding a new account will have Sync for
   17.96 -this account, too, implicitely.
   17.97 -
   17.98 -If Sync is enabled in 2) then adding a new account will have Sync
   17.99 -switched off for this account by default.
    18.1 --- a/test/src/engine_tests/SyncTests.cc	Mon Apr 29 12:15:05 2019 +0200
    18.2 +++ b/test/src/engine_tests/SyncTests.cc	Mon Apr 29 12:15:53 2019 +0200
    18.3 @@ -177,9 +177,9 @@
    18.4  void SyncTests::check_sync()
    18.5  {
    18.6      cout << "check_sync(): trigger KeyGen event\n";
    18.7 -    signal_Sync_event(sync, Sync_PR_keysync, KeyGen);
    18.8 +    signal_Sync_event(sync, Sync_PR_keysync, KeyGen, NULL);
    18.9      adapter.processing();
   18.10  
   18.11      cout << "check_sync(): cry for unknown key\n";
   18.12 -    signal_Sync_event(sync, Sync_PR_keysync, CannotDecrypt);
   18.13 +    signal_Sync_event(sync, Sync_PR_keysync, CannotDecrypt, NULL);
   18.14  }