merged default into branch ENGINE-109
authorKrista Grothoff <krista@pep-project.org>
Mon, 17 Oct 2016 22:38:01 +0200
branchENGINE-109
changeset 1292c310459ec5d3
parent 1282 8e9c3ecdf40f
parent 1290 9d62d6ea3239
child 1293 4f598c491fdf
merged default into branch
     1.1 --- a/asn.1/devicegroup.asn1	Mon Oct 17 13:06:59 2016 +0200
     1.2 +++ b/asn.1/devicegroup.asn1	Mon Oct 17 22:38:01 2016 +0200
     1.3 @@ -19,6 +19,10 @@
     1.4      ownIdentities IdentityList
     1.5  }
     1.6  
     1.7 +GroupUpdate ::= SEQUENCE {
     1.8 +    ownIdentities IdentityList
     1.9 +}
    1.10 +
    1.11  /* for the tags see end of sync.fsm */
    1.12  
    1.13  DeviceGroup-Protocol ::= SEQUENCE {
    1.14 @@ -34,7 +38,8 @@
    1.15      payload CHOICE {
    1.16          beacon [APPLICATION 2] Beacon,
    1.17          handshakeRequest [APPLICATION 3] HandshakeRequest,
    1.18 -        groupKeys [APPLICATION 4] GroupKeys
    1.19 +        groupKeys [APPLICATION 4] GroupKeys,
    1.20 +        groupUpdate [APPLICATION 5] GroupUpdate
    1.21      }
    1.22  }
    1.23  
     2.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Mon Oct 17 13:06:59 2016 +0200
     2.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Mon Oct 17 22:38:01 2016 +0200
     2.3 @@ -40,12 +40,12 @@
     2.4    </ImportGroup>
     2.5    <PropertyGroup Label="UserMacros" />
     2.6    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     2.7 -    <ExecutablePath>C:\Users\vb\bin;$(ExecutablePath)</ExecutablePath>
     2.8 -    <IncludePath>C:\Users\vb\share\asn1c;$(IncludePath)</IncludePath>
     2.9 +    <IncludePath>$(ProjectDir)..\;$(IncludePath)</IncludePath>
    2.10 +    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
    2.11    </PropertyGroup>
    2.12    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    2.13 -    <IncludePath>C:\Users\vb\share\asn1c;$(IncludePath)</IncludePath>
    2.14 -    <ExecutablePath>C:\Users\vb\bin;$(ExecutablePath)</ExecutablePath>
    2.15 +    <IncludePath>$(ProjectDir)..\;$(IncludePath)</IncludePath>
    2.16 +    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
    2.17    </PropertyGroup>
    2.18    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    2.19      <ClCompile>
    2.20 @@ -61,9 +61,8 @@
    2.21        <GenerateDebugInformation>true</GenerateDebugInformation>
    2.22      </Link>
    2.23      <PreBuildEvent>
    2.24 -      <Command>cd ..
    2.25 -asn1c -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1
    2.26 -del converter-sample.c
    2.27 +      <Command>cd "$(ProjectDir).." &amp;&amp; "%ASN1C%\bin\asn1c" -S "%ASN1C%\share\asn1c" -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1 protocols.asn1
    2.28 +cd "$(ProjectDir).." &amp;&amp; del converter-sample.c
    2.29  </Command>
    2.30      </PreBuildEvent>
    2.31      <PreBuildEvent>
    2.32 @@ -99,11 +98,8 @@
    2.33        <OptimizeReferences>true</OptimizeReferences>
    2.34      </Link>
    2.35      <PreBuildEvent>
    2.36 -      <Command>cd ..
    2.37 -del *.c
    2.38 -del *.h
    2.39 -asn1c -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1
    2.40 -del converter-sample.c
    2.41 +      <Command>cd "$(ProjectDir).." &amp;&amp; "%ASN1C%\bin\asn1c" -S "%ASN1C%\share\asn1c" -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1 protocols.asn1
    2.42 +cd "$(ProjectDir).." &amp;&amp; del converter-sample.c
    2.43  </Command>
    2.44        <Message>compiling ASN.1 description</Message>
    2.45      </PreBuildEvent>
    2.46 @@ -142,6 +138,7 @@
    2.47      <ClCompile Include="..\der_encoder.c" />
    2.48      <ClCompile Include="..\DeviceGroup-Protocol.c" />
    2.49      <ClCompile Include="..\GroupKeys.c" />
    2.50 +    <ClCompile Include="..\GroupUpdate.c" />
    2.51      <ClCompile Include="..\HandshakeRequest.c" />
    2.52      <ClCompile Include="..\Hash.c" />
    2.53      <ClCompile Include="..\Hex.c" />
    2.54 @@ -188,6 +185,7 @@
    2.55      <ClInclude Include="..\der_encoder.h" />
    2.56      <ClInclude Include="..\DeviceGroup-Protocol.h" />
    2.57      <ClInclude Include="..\GroupKeys.h" />
    2.58 +    <ClInclude Include="..\GroupUpdate.h" />
    2.59      <ClInclude Include="..\HandshakeRequest.h" />
    2.60      <ClInclude Include="..\Hash.h" />
    2.61      <ClInclude Include="..\Hex.h" />
     3.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj.filters	Mon Oct 17 13:06:59 2016 +0200
     3.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj.filters	Mon Oct 17 22:38:01 2016 +0200
     3.3 @@ -138,6 +138,9 @@
     3.4      <ClCompile Include="..\Sync-Protocols.c">
     3.5        <Filter>Source Files</Filter>
     3.6      </ClCompile>
     3.7 +    <ClCompile Include="..\GroupUpdate.c">
     3.8 +      <Filter>Source Files</Filter>
     3.9 +    </ClCompile>
    3.10    </ItemGroup>
    3.11    <ItemGroup>
    3.12      <ClInclude Include="..\DeviceGroup-Protocol.h">
    3.13 @@ -272,5 +275,8 @@
    3.14      <ClInclude Include="..\Sync-Protocols.h">
    3.15        <Filter>Header Files</Filter>
    3.16      </ClInclude>
    3.17 +    <ClInclude Include="..\GroupUpdate.h">
    3.18 +      <Filter>Header Files</Filter>
    3.19 +    </ClInclude>
    3.20    </ItemGroup>
    3.21  </Project>
    3.22 \ No newline at end of file
     4.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Oct 17 13:06:59 2016 +0200
     4.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Oct 17 22:38:01 2016 +0200
     4.3 @@ -11,6 +11,7 @@
     4.4  		4354FF651D6EDF300033069C /* sync_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF641D6EDF300033069C /* sync_impl.c */; };
     4.5  		4354FF691D6EE1A70033069C /* NULL.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF681D6EE1A70033069C /* NULL.c */; };
     4.6  		43BA0F461D7964750059172F /* asn1_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = 43BA0F451D7964750059172F /* asn1_helper.c */; };
     4.7 +		43E9BC6A1DB51A1E00AD2352 /* GroupUpdate.c in Sources */ = {isa = PBXBuildFile; fileRef = 43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */; };
     4.8  		6400FB861B8CA1C6005221E3 /* libnetpgp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 645922521B8BD32B00A5AF93 /* libnetpgp.a */; };
     4.9  		6400FB8B1B8CA1CF005221E3 /* libetpan-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64289E371B8B630200FC617B /* libetpan-ios.a */; };
    4.10  		644297C51BE11CE0002BC73B /* system.db in Resources */ = {isa = PBXBuildFile; fileRef = 64951A1B1BE0FCD800B10E71 /* system.db */; };
    4.11 @@ -191,6 +192,7 @@
    4.12  		4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
    4.13  		4354FF681D6EE1A70033069C /* NULL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NULL.c; path = ../asn.1/NULL.c; sourceTree = "<group>"; };
    4.14  		43BA0F451D7964750059172F /* asn1_helper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn1_helper.c; path = ../src/asn1_helper.c; sourceTree = "<group>"; };
    4.15 +		43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupUpdate.c; path = ../asn.1/GroupUpdate.c; sourceTree = "<group>"; };
    4.16  		644297BF1BE11C65002BC73B /* pEpTrustWords.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = pEpTrustWords.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
    4.17  		644297C11BE11C65002BC73B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
    4.18  		646788871CEB3D120001F54C /* map_asn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = map_asn1.c; path = ../src/map_asn1.c; sourceTree = "<group>"; };
    4.19 @@ -360,6 +362,7 @@
    4.20  		6406CE811CE382F400C14D77 /* asn.1 */ = {
    4.21  			isa = PBXGroup;
    4.22  			children = (
    4.23 +				43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */,
    4.24  				4354FF681D6EE1A70033069C /* NULL.c */,
    4.25  				646C40951D510CD700C63EFF /* asn_application.h */,
    4.26  				646C40961D510CD700C63EFF /* asn_codecs_prim.c */,
    4.27 @@ -790,6 +793,7 @@
    4.28  			buildActionMask = 2147483647;
    4.29  			files = (
    4.30  				64A826871B455D0800EECAF0 /* stringpair.c in Sources */,
    4.31 +				43E9BC6A1DB51A1E00AD2352 /* GroupUpdate.c in Sources */,
    4.32  				646C41341D510CD800C63EFF /* UTF8String.c in Sources */,
    4.33  				64A826831B455D0800EECAF0 /* platform_unix.c in Sources */,
    4.34  				646C40F81D510CD800C63EFF /* ber_tlv_length.c in Sources */,
     5.1 --- a/build-windows/pEpEngine.vcxproj	Mon Oct 17 13:06:59 2016 +0200
     5.2 +++ b/build-windows/pEpEngine.vcxproj	Mon Oct 17 22:38:01 2016 +0200
     5.3 @@ -42,13 +42,13 @@
     5.4    <PropertyGroup Label="UserMacros" />
     5.5    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     5.6      <LinkIncremental>true</LinkIncremental>
     5.7 -    <IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
     5.8      <RunCodeAnalysis>false</RunCodeAnalysis>
     5.9 +    <IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
    5.10      <LibraryPath>$(ProjectDir)\..\..\libetpan\build-windows\Debug;$(LibraryPath)</LibraryPath>
    5.11    </PropertyGroup>
    5.12    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    5.13      <LinkIncremental>false</LinkIncremental>
    5.14 -    <IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
    5.15 +    <IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
    5.16      <LibraryPath>$(ProjectDir)\..\..\libetpan\build-windows\Release;$(LibraryPath)</LibraryPath>
    5.17    </PropertyGroup>
    5.18    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    5.19 @@ -68,8 +68,9 @@
    5.20        <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
    5.21      </Link>
    5.22      <PreBuildEvent>
    5.23 -      <Command>
    5.24 -      </Command>
    5.25 +      <Command>cd "$(ProjectDir)..\sync" &amp;&amp; python "%YML_PATH%\yml2proc" -E utf-8 -y gen_statemachine.ysl2 devicegroup.fsm -o .statemachines
    5.26 +cd "$(ProjectDir)..\sync" &amp;&amp; python "%YML_PATH%\yml2proc" -E utf-8 -ygen_actions_skeleton.ysl2 devicegroup.fsm -o .skeletons
    5.27 +</Command>
    5.28      </PreBuildEvent>
    5.29    </ItemDefinitionGroup>
    5.30    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    5.31 @@ -95,8 +96,9 @@
    5.32        <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
    5.33      </Link>
    5.34      <PreBuildEvent>
    5.35 -      <Command>
    5.36 -      </Command>
    5.37 +      <Command>cd "$(ProjectDir)..\sync" &amp;&amp; python "%YML_PATH%\yml2proc" -E utf-8 -y gen_statemachine.ysl2 devicegroup.fsm -o .statemachines
    5.38 +cd "$(ProjectDir)..\sync" &amp;&amp; python "%YML_PATH%\yml2proc" -E utf-8 -ygen_actions_skeleton.ysl2 devicegroup.fsm -o .skeletons
    5.39 +</Command>
    5.40      </PreBuildEvent>
    5.41    </ItemDefinitionGroup>
    5.42    <ItemGroup>
     6.1 --- a/src/stringpair.c	Mon Oct 17 13:06:59 2016 +0200
     6.2 +++ b/src/stringpair.c	Mon Oct 17 22:38:01 2016 +0200
     6.3 @@ -10,20 +10,22 @@
     6.4  {
     6.5      stringpair_t *pair = NULL;
     6.6  
     6.7 +    // key and value should not be NULL, that's bad style (while legal)
     6.8 +
     6.9      assert(key);
    6.10 -    assert(value),
    6.11 +    assert(value);
    6.12  
    6.13      pair = calloc(1, sizeof(stringpair_t));
    6.14      assert(pair);
    6.15      if (pair == NULL)
    6.16          goto enomem;
    6.17  
    6.18 -    pair->key = strdup(key);
    6.19 +    pair->key = key ? strdup(key) : strdup("");
    6.20      assert(pair->key);
    6.21      if (pair->key == NULL)
    6.22          goto enomem;
    6.23  
    6.24 -    pair->value = strdup(value);
    6.25 +    pair->value = value ? strdup(value) : strdup("");
    6.26      assert(pair->value);
    6.27      if (pair->value == NULL)
    6.28          goto enomem;
     7.1 --- a/src/stringpair.h	Mon Oct 17 13:06:59 2016 +0200
     7.2 +++ b/src/stringpair.h	Mon Oct 17 22:38:01 2016 +0200
     7.3 @@ -16,8 +16,8 @@
     7.4  // new_stringpair() - allocate new stringpair_t
     7.5  //
     7.6  //  parameters:
     7.7 -//      key (in)        utf-8 string used as key; may point to "" but must not be NULL!
     7.8 -//      value (in)      utf-8 string containing the value; may point to "" but must not be NULL!
     7.9 +//      key (in)        utf-8 string used as key, should not be NULL
    7.10 +//      value (in)      utf-8 string containing the value, should not be NULL
    7.11  //
    7.12  //  return value:
    7.13  //      pointer to stringpair_t or NULL on failure
     8.1 --- a/src/sync_fsm.h	Mon Oct 17 13:06:59 2016 +0200
     8.2 +++ b/src/sync_fsm.h	Mon Oct 17 22:38:01 2016 +0200
     8.3 @@ -65,7 +65,8 @@
     8.4      HandshakeRejected, 
     8.5      HandshakeAccepted, 
     8.6      Cancel, 
     8.7 -    Reject
     8.8 +    Reject, 
     8.9 +    GroupUpdate
    8.10  } DeviceState_event;
    8.11  
    8.12  // actions
    8.13 @@ -77,6 +78,7 @@
    8.14  PEP_STATUS acceptHandshake(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
    8.15  PEP_STATUS sendGroupKeys(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
    8.16  PEP_STATUS storeGroupKeys(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
    8.17 +PEP_STATUS sendGroupUpdate(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
    8.18  
    8.19  // event injector
    8.20  
     9.1 --- a/src/sync_impl.c	Mon Oct 17 13:06:59 2016 +0200
     9.2 +++ b/src/sync_impl.c	Mon Oct 17 22:38:01 2016 +0200
     9.3 @@ -70,6 +70,7 @@
     9.4                  break;
     9.5  
     9.6              case DeviceGroup_Protocol__payload_PR_groupKeys:
     9.7 +            case DeviceGroup_Protocol__payload_PR_groupUpdate:
     9.8                  partner = Identity_to_Struct(&msg->header.me, NULL);
     9.9                  if (!partner){
    9.10                      status = PEP_OUT_OF_MEMORY;
    9.11 @@ -77,7 +78,11 @@
    9.12                      goto error;
    9.13                  }
    9.14                  identity_list *group_keys = IdentityList_to_identity_list(
    9.15 -                        &msg->payload.choice.groupKeys.ownIdentities, NULL);
    9.16 +                        msg->payload.present == 
    9.17 +                          DeviceGroup_Protocol__payload_PR_groupKeys ?
    9.18 +                        &msg->payload.choice.groupKeys.ownIdentities :
    9.19 +                        &msg->payload.choice.groupUpdate.ownIdentities,
    9.20 +                        NULL);
    9.21                  if (!group_keys) {
    9.22                      free_identity(partner);
    9.23                      status = PEP_OUT_OF_MEMORY;
    9.24 @@ -85,7 +90,9 @@
    9.25                      goto error;
    9.26                  }
    9.27                  extra = (void *) group_keys;
    9.28 -                event = GroupKeys;
    9.29 +                event = msg->payload.present == 
    9.30 +                          DeviceGroup_Protocol__payload_PR_groupKeys ?
    9.31 +                          GroupKeys : GroupUpdate;
    9.32                  break;
    9.33  
    9.34              default:
    9.35 @@ -283,14 +290,15 @@
    9.36                                  goto free_all;
    9.37                              }
    9.38                              break;
    9.39 -                        // accepting GroupKeys needs encryption and trust
    9.40 +                        // accepting GroupKeys and GroupUpdate needs encryption and trust
    9.41                          case DeviceGroup_Protocol__payload_PR_groupKeys:
    9.42 +                        case DeviceGroup_Protocol__payload_PR_groupUpdate:
    9.43                              if (!keylist || rating < PEP_rating_reliable ||
    9.44 -                                // if header.state is HandshakingSole, then
    9.45 -                                // group is just forming in between 2 devices
    9.46 +                                // if group is just forming in between 2 devices
    9.47                                  // message must be addressed to that instance
    9.48                                  // to be consumed
    9.49 -                                (msg->header.state == HandshakingSole && 
    9.50 +                                (msg->payload.present == 
    9.51 +                                  DeviceGroup_Protocol__payload_PR_groupKeys && 
    9.52                                   strncmp(session->sync_uuid,
    9.53                                          (const char *)msg->payload.choice.groupKeys.partner.user_id->buf,
    9.54                                          msg->payload.choice.groupKeys.partner.user_id->size) != 0)){
    9.55 @@ -302,7 +310,8 @@
    9.56                              // pre-existing group, inject message but flag is 
    9.57                              // as discarded to prevent app to delete it, so 
    9.58                              // that other group members can also be updated
    9.59 -                            if(msg->header.state != HandshakingSole){
    9.60 +                            if (msg->payload.present == 
    9.61 +                                  DeviceGroup_Protocol__payload_PR_groupUpdate){
    9.62                                  force_keep_msg = true;
    9.63                              }
    9.64  
    9.65 @@ -504,7 +513,8 @@
    9.66      me = NULL;
    9.67  
    9.68      if (encrypted) {
    9.69 -        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupKeys) {
    9.70 +        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupKeys || 
    9.71 +            msg->payload.present == DeviceGroup_Protocol__payload_PR_groupUpdate) {
    9.72              PEP_rating rating = PEP_rating_undefined;
    9.73              status = outgoing_message_rating(session, _message, &rating);
    9.74              if (status != PEP_STATUS_OK)
    9.75 @@ -514,7 +524,12 @@
    9.76                  goto error;
    9.77              }
    9.78              
    9.79 -            IdentityList_t *list = &msg->payload.choice.groupKeys.ownIdentities;
    9.80 +            IdentityList_t *list = 
    9.81 +                msg->payload.present == 
    9.82 +                  DeviceGroup_Protocol__payload_PR_groupKeys ?
    9.83 +                  &msg->payload.choice.groupKeys.ownIdentities :
    9.84 +                  &msg->payload.choice.groupUpdate.ownIdentities;
    9.85 +
    9.86              for (int i=0; i<list->list.count; i++) {
    9.87                  Identity_t *ident = list->list.array[i];
    9.88                  char *fpr = strndup((const char *)ident->fpr.buf, ident->fpr.size);
    9.89 @@ -582,25 +597,31 @@
    9.90      if (status != PEP_STATUS_OK)
    9.91          return status;
    9.92  
    9.93 +    printf("BROADCAST \n");
    9.94 +
    9.95      // FIXME: exclude previously rejected identities
    9.96      for (identity_list *_i = own_identities; _i && _i->ident; _i = _i->next) {
    9.97          pEp_identity *me = _i->ident;
    9.98  
    9.99 +        printf("BROADCAST looop \n");
   9.100          // FIXME: no deep copy for multicast supported yet
   9.101 -        DeviceGroup_Protocol_t *_msg = malloc(sizeof(DeviceGroup_Protocol_t));
   9.102 -        assert(_msg);
   9.103 -        if (_msg == NULL)
   9.104 -            goto enomem;
   9.105 -        memcpy(_msg, msg, sizeof(DeviceGroup_Protocol_t));
   9.106 -        status = unicast_msg(session, me, state, _msg, encrypted);
   9.107 -        free_DeviceGroup_Protocol_msg(_msg);
   9.108 +        // DeviceGroup_Protocol_t *_msg = malloc(sizeof(DeviceGroup_Protocol_t));
   9.109 +        // assert(_msg);
   9.110 +        // if (_msg == NULL){
   9.111 +        //     status = PEP_OUT_OF_MEMORY;
   9.112 +        //     goto error;
   9.113 +        // }
   9.114 +        // memcpy(_msg, msg, sizeof(DeviceGroup_Protocol_t));
   9.115 +        status = unicast_msg(session, me, state, msg, encrypted);
   9.116 +        //status = unicast_msg(session, me, state, _msg, encrypted);
   9.117 +        //free_DeviceGroup_Protocol_msg(_msg);
   9.118      }
   9.119  
   9.120      free_identity_list(own_identities);
   9.121      return PEP_STATUS_OK;
   9.122  
   9.123 -enomem:
   9.124 -    free_identity_list(own_identities);
   9.125 -    return PEP_OUT_OF_MEMORY;
   9.126 +// error:
   9.127 +//     free_identity_list(own_identities);
   9.128 +//     return status;
   9.129  }
   9.130  
    10.1 --- a/src/sync_send_actions.c	Mon Oct 17 13:06:59 2016 +0200
    10.2 +++ b/src/sync_send_actions.c	Mon Oct 17 22:38:01 2016 +0200
    10.3 @@ -12,6 +12,7 @@
    10.4  #include "../asn.1/Beacon.h"
    10.5  #include "../asn.1/HandshakeRequest.h"
    10.6  #include "../asn.1/GroupKeys.h"
    10.7 +#include "../asn.1/GroupUpdate.h"
    10.8  
    10.9  
   10.10  // sendBeacon() - send Beacon message
   10.11 @@ -159,3 +160,54 @@
   10.12      return status;
   10.13  }
   10.14  
   10.15 +
   10.16 +// sendGroupUpdate() - send GroupUpdate message
   10.17 +//
   10.18 +//  params:
   10.19 +//      session (in)        session handle
   10.20 +//      state (in)          state the state machine is in
   10.21 +//      partner (in)        (must be NULL)
   10.22 +//
   10.23 +//  returns:
   10.24 +//      PEP_STATUS_OK or any other value on error
   10.25 +
   10.26 +PEP_STATUS sendGroupUpdate(
   10.27 +        PEP_SESSION session,
   10.28 +        DeviceState_state state,
   10.29 +        Identity partner,
   10.30 +        void *extra
   10.31 +    )
   10.32 +{
   10.33 +    assert(session && state);
   10.34 +    if (!(session && state))
   10.35 +        return PEP_ILLEGAL_VALUE;
   10.36 +
   10.37 +    PEP_STATUS status = PEP_STATUS_OK;
   10.38 +    identity_list *kl = new_identity_list(NULL);
   10.39 +
   10.40 +    DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_groupUpdate);
   10.41 +    if (!msg)
   10.42 +        goto enomem;
   10.43 +
   10.44 +    status = own_identities_retrieve(session, &kl);
   10.45 +    if (status != PEP_STATUS_OK)
   10.46 +        goto error;
   10.47 +    if (IdentityList_from_identity_list(kl, &msg->payload.choice.groupUpdate.ownIdentities) == NULL)
   10.48 +        goto enomem;
   10.49 +
   10.50 +    bool encrypted = true;
   10.51 +    status = multicast_self_msg(session, state, msg, encrypted);
   10.52 +    if (status != PEP_STATUS_OK)
   10.53 +        goto error;
   10.54 +
   10.55 +    free_identity_list(kl);
   10.56 +    free_DeviceGroup_Protocol_msg(msg);
   10.57 +    return PEP_STATUS_OK;
   10.58 +
   10.59 +enomem:
   10.60 +    status = PEP_OUT_OF_MEMORY;
   10.61 +error:
   10.62 +    free_DeviceGroup_Protocol_msg(msg);
   10.63 +    return status;
   10.64 +}
   10.65 +
    11.1 --- a/sync/devicegroup.fsm	Mon Oct 17 13:06:59 2016 +0200
    11.2 +++ b/sync/devicegroup.fsm	Mon Oct 17 22:38:01 2016 +0200
    11.3 @@ -10,6 +10,7 @@
    11.4      // all messages have a timestamp, time out and are removed after timeout
    11.5  
    11.6      broadcast sendBeacon;
    11.7 +    broadcast sendGroupUpdate;
    11.8      unencrypted sendBeacon;
    11.9  
   11.10      fsm DeviceState filename=sync {
   11.11 @@ -59,7 +60,6 @@
   11.12          state WaitForGroupKeysSole(Identity partner) {
   11.13              on GroupKeys(Identity partner, Stringlist keys) {
   11.14                  do storeGroupKeys(partner, keys);
   11.15 -                // TODO : add a callback to signal finished waiting for group keys
   11.16                  go Grouped;
   11.17              }
   11.18              on Cancel go Sole;
   11.19 @@ -71,18 +71,15 @@
   11.20  
   11.21          state Grouped {
   11.22              on KeyGen
   11.23 -                do sendGroupKeys; // always send all keys
   11.24 +                do sendGroupUpdate;
   11.25              on Beacon(Identity partner)
   11.26                  do sendHandshakeRequest(partner);
   11.27              on HandshakeRequest(Identity partner) {
   11.28                  do sendHandshakeRequest(partner);
   11.29                  go HandshakingGrouped(partner);
   11.30              }
   11.31 -            on GroupKeys(Identity partner, Stringlist keys) {
   11.32 +            on GroupUpdate(Identity partner, Stringlist keys)
   11.33                  do storeGroupKeys(partner, keys);
   11.34 -                // TODO : add a callback to signal finished waiting for group keys
   11.35 -                go Grouped;
   11.36 -            }
   11.37          }
   11.38  
   11.39          state HandshakingGrouped(Identity partner) {
    12.1 --- a/sync/gen_actions_skeleton.ysl2	Mon Oct 17 13:06:59 2016 +0200
    12.2 +++ b/sync/gen_actions_skeleton.ysl2	Mon Oct 17 22:38:01 2016 +0200
    12.3 @@ -160,19 +160,19 @@
    12.4                  return PEP_ILLEGAL_VALUE;
    12.5  
    12.6              PEP_STATUS status = PEP_STATUS_OK;
    12.7 -            `` if "$name='GroupKeys'" |> identity_list *kl = new_identity_list(NULL);
    12.8 +            `` if "$name='GroupKeys' or $name='GroupUpdate'" |> identity_list *kl = new_identity_list(NULL);
    12.9  
   12.10              DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_«$lname»);
   12.11              if (!msg)
   12.12                  goto enomem;
   12.13          ||
   12.14          choose {
   12.15 -            when "$name='GroupKeys'" {
   12.16 +            when "$name='GroupKeys' or $name='GroupUpdate'" {
   12.17                  |
   12.18                  |> status = own_identities_retrieve(session, &kl);
   12.19                  |> if (status != PEP_STATUS_OK)
   12.20                  |>> goto error;
   12.21 -                |> if (IdentityList_from_identity_list(kl, &msg->payload.choice.groupKeys.ownIdentities) == NULL)
   12.22 +                |> if (IdentityList_from_identity_list(kl, &msg->payload.choice.«$lname».ownIdentities) == NULL)
   12.23                  |>> goto enomem;
   12.24              }
   12.25          }
   12.26 @@ -203,7 +203,7 @@
   12.27              if (status != PEP_STATUS_OK)
   12.28                  goto error;
   12.29  
   12.30 -            `` if "$name='GroupKeys'" |> free_identity_list(kl);
   12.31 +            `` if "$name='GroupKeys' or $name='GroupUpdate'" |> free_identity_list(kl);
   12.32              free_DeviceGroup_Protocol_msg(msg);
   12.33              return PEP_STATUS_OK;
   12.34