KEYSYNC: #comment Merged keysync into default. Please commit to default, not keysync anymore, unless you are [~edouard]
authorKrista Grothoff <krista@pep-project.org>
Wed, 05 Oct 2016 15:38:42 +0200
changeset 1247998021d725a1
parent 1231 fc71de0ef4a1
parent 1245 d0c63eb5bfa6
child 1248 c332c47fe26e
KEYSYNC: #comment Merged keysync into default. Please commit to default, not keysync anymore, unless you are [~edouard]
     1.1 --- a/.hgignore	Mon Oct 03 14:34:58 2016 +0200
     1.2 +++ b/.hgignore	Wed Oct 05 15:38:42 2016 +0200
     1.3 @@ -37,3 +37,6 @@
     1.4  .skeletons
     1.5  .statemachines
     1.6  Makefile.protocols
     1.7 +test/msg_encrypt_for_self.asc
     1.8 +tags
     1.9 +asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj.user
     2.1 --- a/Makefile.conf	Mon Oct 03 14:34:58 2016 +0200
     2.2 +++ b/Makefile.conf	Wed Oct 05 15:38:42 2016 +0200
     2.3 @@ -18,3 +18,9 @@
     2.4  # DEFAULT_KEYSERVER - string with default keyserver
     2.5  # CRASHDUMP_DEFAULT_LINES - number of log lines to deliver for crashdumps
     2.6  
     2.7 +#EXTRAMACROS=-DDEFAULT_KEYSERVER=\"default-server.org\" -DCRASHDUMP_DEFAULT_LINES=23
     2.8 +
     2.9 +# second instance for testing
    2.10 +
    2.11 +#EXTRAMACROS=-DLOCAL_DB_FILENAME=\".pEp_management2.db\"
    2.12 +#TARGET=libpEpEngine2.dylib 
     3.1 --- a/README-OSX.md	Mon Oct 03 14:34:58 2016 +0200
     3.2 +++ b/README-OSX.md	Wed Oct 05 15:38:42 2016 +0200
     3.3 @@ -40,9 +40,7 @@
     3.4  
     3.5  ```
     3.6  pushd ~
     3.7 -curl -LO http://fdik.org/yml2.tar.bz2
     3.8 -tar xf yml2.tar.bz2
     3.9 -rm yml2.tar.bz2*
    3.10 +hg clone https://cacert.pep.foundation/dev/repos/yml2/
    3.11  popd
    3.12  ```
    3.13  
     4.1 --- a/asn.1/devicegroup.asn1	Mon Oct 03 14:34:58 2016 +0200
     4.2 +++ b/asn.1/devicegroup.asn1	Wed Oct 05 15:38:42 2016 +0200
     4.3 @@ -6,34 +6,36 @@
     4.4  BEGIN
     4.5  
     4.6  EXPORTS DeviceGroup-Protocol;
     4.7 -IMPORTS Identity, KeyList, Header FROM PEP;
     4.8 +IMPORTS Version, Identity, IdentityList FROM PEP;
     4.9  
    4.10 -Beacon ::= SEQUENCE {
    4.11 -    header Header,
    4.12 -    state INTEGER,
    4.13 -    me Identity
    4.14 -}
    4.15 +Beacon ::= NULL
    4.16  
    4.17  HandshakeRequest ::= SEQUENCE {
    4.18 -    header Header,
    4.19 -    state INTEGER,
    4.20 -    me Identity,
    4.21 -    partner Identity
    4.22 +    partner Identity /* identity of the receiver */
    4.23  }
    4.24  
    4.25  GroupKeys ::= SEQUENCE {
    4.26 -    header Header,
    4.27 -    state INTEGER,
    4.28 -    me Identity,
    4.29 -    keylist KeyList
    4.30 +    partner Identity, /* identity of the receiver */
    4.31 +    ownIdentities IdentityList
    4.32  }
    4.33  
    4.34  /* for the tags see end of sync.fsm */
    4.35  
    4.36 -DeviceGroup-Protocol ::= CHOICE {
    4.37 -    beacon [APPLICATION 1] Beacon,
    4.38 -    handshakeRequest [APPLICATION 2] HandshakeRequest,
    4.39 -    groupKeys [APPLICATION 3] GroupKeys
    4.40 +DeviceGroup-Protocol ::= SEQUENCE {
    4.41 +    header SEQUENCE {
    4.42 +        version     Version,
    4.43 +        sequence    INTEGER,  /* always increases */
    4.44 +        me          Identity, /* identity of the sender */
    4.45 +        state       INTEGER,  /* state the sender is in */
    4.46 +        devicegroup BOOLEAN
    4.47 +            /* signals if this message is coming from a device group member */
    4.48 +    },
    4.49 +
    4.50 +    payload CHOICE {
    4.51 +        beacon [APPLICATION 2] Beacon,
    4.52 +        handshakeRequest [APPLICATION 3] HandshakeRequest,
    4.53 +        groupKeys [APPLICATION 4] GroupKeys
    4.54 +    }
    4.55  }
    4.56  
    4.57  END
     5.1 --- a/asn.1/pEp.asn1	Mon Oct 03 14:34:58 2016 +0200
     5.2 +++ b/asn.1/pEp.asn1	Wed Oct 05 15:38:42 2016 +0200
     5.3 @@ -5,10 +5,7 @@
     5.4  
     5.5  BEGIN
     5.6  
     5.7 -EXPORTS Identity, KeyList, Header;
     5.8 -
     5.9 -major-version INTEGER ::= 1
    5.10 -minor-version INTEGER ::= 0
    5.11 +EXPORTS Version, Identity, IdentityList;
    5.12  
    5.13  ISO639-1 ::= PrintableString(FROM ("a".."z")) (SIZE(2))
    5.14  Hex ::= PrintableString(FROM ("A".."F") | FROM ("0".."9"))
    5.15 @@ -20,19 +17,14 @@
    5.16      user-id     UTF8String  (SIZE(1..1024)) OPTIONAL,
    5.17      username    UTF8String  (SIZE(1..1024)) OPTIONAL,
    5.18      comm-type   INTEGER     (0..255) OPTIONAL,
    5.19 -    lang        ISO639-1    DEFAULT "en"
    5.20 +    lang        ISO639-1
    5.21  }
    5.22  
    5.23 -KeyList ::= SEQUENCE OF Hash
    5.24 +IdentityList ::= SEQUENCE OF Identity
    5.25  
    5.26  Version ::= SEQUENCE {
    5.27 -    major       INTEGER (0..255) DEFAULT major-version,
    5.28 -    minor       INTEGER (0..255) DEFAULT minor-version
    5.29 -}
    5.30 -
    5.31 -Header ::= SEQUENCE {
    5.32 -    version     Version,
    5.33 -    sequence    INTEGER
    5.34 +    major       INTEGER (0..255),
    5.35 +    minor       INTEGER (0..255)
    5.36  }
    5.37  
    5.38  END
     6.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Mon Oct 03 14:34:58 2016 +0200
     6.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Wed Oct 05 15:38:42 2016 +0200
     6.3 @@ -54,7 +54,7 @@
     6.4        <WarningLevel>Level3</WarningLevel>
     6.5        <Optimization>Disabled</Optimization>
     6.6        <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     6.7 -	  <CompileAs>Default</CompileAs>
     6.8 +      <CompileAs>Default</CompileAs>
     6.9      </ClCompile>
    6.10      <Link>
    6.11        <SubSystem>Windows</SubSystem>
    6.12 @@ -100,6 +100,8 @@
    6.13      </Link>
    6.14      <PreBuildEvent>
    6.15        <Command>cd ..
    6.16 +del *.c
    6.17 +del *.h
    6.18  asn1c -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1
    6.19  del converter-sample.c
    6.20  </Command>
    6.21 @@ -130,6 +132,7 @@
    6.22      <ClCompile Include="..\ber_tlv_length.c" />
    6.23      <ClCompile Include="..\ber_tlv_tag.c" />
    6.24      <ClCompile Include="..\BIT_STRING.c" />
    6.25 +    <ClCompile Include="..\BOOLEAN.c" />
    6.26      <ClCompile Include="..\constraints.c" />
    6.27      <ClCompile Include="..\constr_CHOICE.c" />
    6.28      <ClCompile Include="..\constr_SEQUENCE.c" />
    6.29 @@ -141,20 +144,21 @@
    6.30      <ClCompile Include="..\GroupKeys.c" />
    6.31      <ClCompile Include="..\HandshakeRequest.c" />
    6.32      <ClCompile Include="..\Hash.c" />
    6.33 -    <ClCompile Include="..\Header.c" />
    6.34      <ClCompile Include="..\Hex.c" />
    6.35      <ClCompile Include="..\Identity.c" />
    6.36 +    <ClCompile Include="..\IdentityList.c" />
    6.37      <ClCompile Include="..\INTEGER.c" />
    6.38      <ClCompile Include="..\ISO639-1.c" />
    6.39 -    <ClCompile Include="..\KeyList.c" />
    6.40      <ClCompile Include="..\NativeEnumerated.c" />
    6.41      <ClCompile Include="..\NativeInteger.c" />
    6.42 +    <ClCompile Include="..\NULL.c" />
    6.43      <ClCompile Include="..\OCTET_STRING.c" />
    6.44      <ClCompile Include="..\per_decoder.c" />
    6.45      <ClCompile Include="..\per_encoder.c" />
    6.46      <ClCompile Include="..\per_opentype.c" />
    6.47      <ClCompile Include="..\per_support.c" />
    6.48      <ClCompile Include="..\PrintableString.c" />
    6.49 +    <ClCompile Include="..\Sync-Protocols.c" />
    6.50      <ClCompile Include="..\UTF8String.c" />
    6.51      <ClCompile Include="..\Version.c" />
    6.52      <ClCompile Include="..\xer_decoder.c" />
    6.53 @@ -174,6 +178,7 @@
    6.54      <ClInclude Include="..\ber_tlv_length.h" />
    6.55      <ClInclude Include="..\ber_tlv_tag.h" />
    6.56      <ClInclude Include="..\BIT_STRING.h" />
    6.57 +    <ClInclude Include="..\BOOLEAN.h" />
    6.58      <ClInclude Include="..\constraints.h" />
    6.59      <ClInclude Include="..\constr_CHOICE.h" />
    6.60      <ClInclude Include="..\constr_SEQUENCE.h" />
    6.61 @@ -185,21 +190,21 @@
    6.62      <ClInclude Include="..\GroupKeys.h" />
    6.63      <ClInclude Include="..\HandshakeRequest.h" />
    6.64      <ClInclude Include="..\Hash.h" />
    6.65 -    <ClInclude Include="..\Header.h" />
    6.66      <ClInclude Include="..\Hex.h" />
    6.67      <ClInclude Include="..\Identity.h" />
    6.68 +    <ClInclude Include="..\IdentityList.h" />
    6.69      <ClInclude Include="..\INTEGER.h" />
    6.70      <ClInclude Include="..\ISO639-1.h" />
    6.71 -    <ClInclude Include="..\KeyList.h" />
    6.72      <ClInclude Include="..\NativeEnumerated.h" />
    6.73      <ClInclude Include="..\NativeInteger.h" />
    6.74 +    <ClInclude Include="..\NULL.h" />
    6.75      <ClInclude Include="..\OCTET_STRING.h" />
    6.76 -    <ClInclude Include="..\OwnKeys.h" />
    6.77      <ClInclude Include="..\per_decoder.h" />
    6.78      <ClInclude Include="..\per_encoder.h" />
    6.79      <ClInclude Include="..\per_opentype.h" />
    6.80      <ClInclude Include="..\per_support.h" />
    6.81      <ClInclude Include="..\PrintableString.h" />
    6.82 +    <ClInclude Include="..\Sync-Protocols.h" />
    6.83      <ClInclude Include="..\UTF8String.h" />
    6.84      <ClInclude Include="..\Version.h" />
    6.85      <ClInclude Include="..\xer_decoder.h" />
     7.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj.filters	Mon Oct 03 14:34:58 2016 +0200
     7.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj.filters	Wed Oct 05 15:38:42 2016 +0200
     7.3 @@ -72,9 +72,6 @@
     7.4      <ClCompile Include="..\Hash.c">
     7.5        <Filter>Source Files</Filter>
     7.6      </ClCompile>
     7.7 -    <ClCompile Include="..\Header.c">
     7.8 -      <Filter>Source Files</Filter>
     7.9 -    </ClCompile>
    7.10      <ClCompile Include="..\Hex.c">
    7.11        <Filter>Source Files</Filter>
    7.12      </ClCompile>
    7.13 @@ -87,9 +84,6 @@
    7.14      <ClCompile Include="..\ISO639-1.c">
    7.15        <Filter>Source Files</Filter>
    7.16      </ClCompile>
    7.17 -    <ClCompile Include="..\KeyList.c">
    7.18 -      <Filter>Source Files</Filter>
    7.19 -    </ClCompile>
    7.20      <ClCompile Include="..\NativeEnumerated.c">
    7.21        <Filter>Source Files</Filter>
    7.22      </ClCompile>
    7.23 @@ -132,6 +126,18 @@
    7.24      <ClCompile Include="..\GroupKeys.c">
    7.25        <Filter>Source Files</Filter>
    7.26      </ClCompile>
    7.27 +    <ClCompile Include="..\BOOLEAN.c">
    7.28 +      <Filter>Source Files</Filter>
    7.29 +    </ClCompile>
    7.30 +    <ClCompile Include="..\IdentityList.c">
    7.31 +      <Filter>Source Files</Filter>
    7.32 +    </ClCompile>
    7.33 +    <ClCompile Include="..\NULL.c">
    7.34 +      <Filter>Source Files</Filter>
    7.35 +    </ClCompile>
    7.36 +    <ClCompile Include="..\Sync-Protocols.c">
    7.37 +      <Filter>Source Files</Filter>
    7.38 +    </ClCompile>
    7.39    </ItemGroup>
    7.40    <ItemGroup>
    7.41      <ClInclude Include="..\DeviceGroup-Protocol.h">
    7.42 @@ -200,9 +206,6 @@
    7.43      <ClInclude Include="..\Hash.h">
    7.44        <Filter>Header Files</Filter>
    7.45      </ClInclude>
    7.46 -    <ClInclude Include="..\Header.h">
    7.47 -      <Filter>Header Files</Filter>
    7.48 -    </ClInclude>
    7.49      <ClInclude Include="..\Hex.h">
    7.50        <Filter>Header Files</Filter>
    7.51      </ClInclude>
    7.52 @@ -215,9 +218,6 @@
    7.53      <ClInclude Include="..\ISO639-1.h">
    7.54        <Filter>Header Files</Filter>
    7.55      </ClInclude>
    7.56 -    <ClInclude Include="..\KeyList.h">
    7.57 -      <Filter>Header Files</Filter>
    7.58 -    </ClInclude>
    7.59      <ClInclude Include="..\NativeEnumerated.h">
    7.60        <Filter>Header Files</Filter>
    7.61      </ClInclude>
    7.62 @@ -227,9 +227,6 @@
    7.63      <ClInclude Include="..\OCTET_STRING.h">
    7.64        <Filter>Header Files</Filter>
    7.65      </ClInclude>
    7.66 -    <ClInclude Include="..\OwnKeys.h">
    7.67 -      <Filter>Header Files</Filter>
    7.68 -    </ClInclude>
    7.69      <ClInclude Include="..\per_decoder.h">
    7.70        <Filter>Header Files</Filter>
    7.71      </ClInclude>
    7.72 @@ -263,5 +260,17 @@
    7.73      <ClInclude Include="..\GroupKeys.h">
    7.74        <Filter>Header Files</Filter>
    7.75      </ClInclude>
    7.76 +    <ClInclude Include="..\BOOLEAN.h">
    7.77 +      <Filter>Header Files</Filter>
    7.78 +    </ClInclude>
    7.79 +    <ClInclude Include="..\IdentityList.h">
    7.80 +      <Filter>Header Files</Filter>
    7.81 +    </ClInclude>
    7.82 +    <ClInclude Include="..\NULL.h">
    7.83 +      <Filter>Header Files</Filter>
    7.84 +    </ClInclude>
    7.85 +    <ClInclude Include="..\Sync-Protocols.h">
    7.86 +      <Filter>Header Files</Filter>
    7.87 +    </ClInclude>
    7.88    </ItemGroup>
    7.89  </Project>
    7.90 \ No newline at end of file
     8.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Oct 03 14:34:58 2016 +0200
     8.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Wed Oct 05 15:38:42 2016 +0200
     8.3 @@ -8,74 +8,105 @@
     8.4  
     8.5  /* Begin PBXBuildFile section */
     8.6  		430D258B1C9ED75A00B94535 /* blacklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 430D258A1C9ED75A00B94535 /* blacklist.c */; };
     8.7 +		4354FF651D6EDF300033069C /* sync_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF641D6EDF300033069C /* sync_impl.c */; };
     8.8 +		4354FF691D6EE1A70033069C /* NULL.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF681D6EE1A70033069C /* NULL.c */; };
     8.9 +		43BA0F461D7964750059172F /* asn1_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = 43BA0F451D7964750059172F /* asn1_helper.c */; };
    8.10  		6400FB861B8CA1C6005221E3 /* libnetpgp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 645922521B8BD32B00A5AF93 /* libnetpgp.a */; };
    8.11  		6400FB8B1B8CA1CF005221E3 /* libetpan-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64289E371B8B630200FC617B /* libetpan-ios.a */; };
    8.12 -		6406CEC51CE3835300C14D77 /* asn_application.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE861CE3835300C14D77 /* asn_application.h */; };
    8.13 -		6406CEC61CE3835300C14D77 /* asn_codecs_prim.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE871CE3835300C14D77 /* asn_codecs_prim.c */; };
    8.14 -		6406CEC71CE3835300C14D77 /* asn_codecs_prim.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE881CE3835300C14D77 /* asn_codecs_prim.h */; };
    8.15 -		6406CEC81CE3835300C14D77 /* asn_codecs.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE891CE3835300C14D77 /* asn_codecs.h */; };
    8.16 -		6406CEC91CE3835300C14D77 /* asn_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE8A1CE3835300C14D77 /* asn_internal.h */; };
    8.17 -		6406CECA1CE3835300C14D77 /* asn_SEQUENCE_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE8B1CE3835300C14D77 /* asn_SEQUENCE_OF.c */; };
    8.18 -		6406CECB1CE3835300C14D77 /* asn_SEQUENCE_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE8C1CE3835300C14D77 /* asn_SEQUENCE_OF.h */; };
    8.19 -		6406CECC1CE3835300C14D77 /* asn_SET_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE8D1CE3835300C14D77 /* asn_SET_OF.c */; };
    8.20 -		6406CECD1CE3835300C14D77 /* asn_SET_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE8E1CE3835300C14D77 /* asn_SET_OF.h */; };
    8.21 -		6406CECE1CE3835300C14D77 /* asn_system.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE8F1CE3835300C14D77 /* asn_system.h */; };
    8.22 -		6406CECF1CE3835300C14D77 /* ber_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE901CE3835300C14D77 /* ber_decoder.c */; };
    8.23 -		6406CED01CE3835300C14D77 /* ber_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE911CE3835300C14D77 /* ber_decoder.h */; };
    8.24 -		6406CED11CE3835300C14D77 /* ber_tlv_length.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE921CE3835300C14D77 /* ber_tlv_length.c */; };
    8.25 -		6406CED21CE3835300C14D77 /* ber_tlv_length.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE931CE3835300C14D77 /* ber_tlv_length.h */; };
    8.26 -		6406CED31CE3835300C14D77 /* ber_tlv_tag.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE941CE3835300C14D77 /* ber_tlv_tag.c */; };
    8.27 -		6406CED41CE3835300C14D77 /* ber_tlv_tag.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE951CE3835300C14D77 /* ber_tlv_tag.h */; };
    8.28 -		6406CED51CE3835300C14D77 /* BIT_STRING.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE961CE3835300C14D77 /* BIT_STRING.c */; };
    8.29 -		6406CED61CE3835300C14D77 /* BIT_STRING.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE971CE3835300C14D77 /* BIT_STRING.h */; };
    8.30 -		6406CED71CE3835300C14D77 /* constr_SEQUENCE_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE981CE3835300C14D77 /* constr_SEQUENCE_OF.c */; };
    8.31 -		6406CED81CE3835300C14D77 /* constr_SEQUENCE_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE991CE3835300C14D77 /* constr_SEQUENCE_OF.h */; };
    8.32 -		6406CED91CE3835300C14D77 /* constr_SEQUENCE.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE9A1CE3835300C14D77 /* constr_SEQUENCE.c */; };
    8.33 -		6406CEDA1CE3835300C14D77 /* constr_SEQUENCE.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE9B1CE3835300C14D77 /* constr_SEQUENCE.h */; };
    8.34 -		6406CEDB1CE3835300C14D77 /* constr_SET_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE9C1CE3835300C14D77 /* constr_SET_OF.c */; };
    8.35 -		6406CEDC1CE3835300C14D77 /* constr_SET_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE9D1CE3835300C14D77 /* constr_SET_OF.h */; };
    8.36 -		6406CEDD1CE3835300C14D77 /* constr_TYPE.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CE9E1CE3835300C14D77 /* constr_TYPE.c */; };
    8.37 -		6406CEDE1CE3835300C14D77 /* constr_TYPE.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CE9F1CE3835300C14D77 /* constr_TYPE.h */; };
    8.38 -		6406CEDF1CE3835300C14D77 /* constraints.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEA01CE3835300C14D77 /* constraints.c */; };
    8.39 -		6406CEE01CE3835300C14D77 /* constraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEA11CE3835300C14D77 /* constraints.h */; };
    8.40 -		6406CEE11CE3835300C14D77 /* der_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEA21CE3835300C14D77 /* der_encoder.c */; };
    8.41 -		6406CEE21CE3835300C14D77 /* der_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEA31CE3835300C14D77 /* der_encoder.h */; };
    8.42 -		6406CEE31CE3835300C14D77 /* Identity.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEA41CE3835300C14D77 /* Identity.c */; };
    8.43 -		6406CEE41CE3835300C14D77 /* Identity.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEA51CE3835300C14D77 /* Identity.h */; };
    8.44 -		6406CEE51CE3835300C14D77 /* INTEGER.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEA61CE3835300C14D77 /* INTEGER.c */; };
    8.45 -		6406CEE61CE3835300C14D77 /* INTEGER.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEA71CE3835300C14D77 /* INTEGER.h */; };
    8.46 -		6406CEE71CE3835300C14D77 /* NativeEnumerated.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEA91CE3835300C14D77 /* NativeEnumerated.c */; };
    8.47 -		6406CEE81CE3835300C14D77 /* NativeEnumerated.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEAA1CE3835300C14D77 /* NativeEnumerated.h */; };
    8.48 -		6406CEE91CE3835300C14D77 /* NativeInteger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEAB1CE3835300C14D77 /* NativeInteger.c */; };
    8.49 -		6406CEEA1CE3835300C14D77 /* NativeInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEAC1CE3835300C14D77 /* NativeInteger.h */; };
    8.50 -		6406CEEB1CE3835300C14D77 /* OCTET_STRING.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEAD1CE3835300C14D77 /* OCTET_STRING.c */; };
    8.51 -		6406CEEC1CE3835300C14D77 /* OCTET_STRING.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEAE1CE3835300C14D77 /* OCTET_STRING.h */; };
    8.52 -		6406CEED1CE3835300C14D77 /* per_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEAF1CE3835300C14D77 /* per_decoder.c */; };
    8.53 -		6406CEEE1CE3835300C14D77 /* per_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEB01CE3835300C14D77 /* per_decoder.h */; };
    8.54 -		6406CEEF1CE3835300C14D77 /* per_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEB11CE3835300C14D77 /* per_encoder.c */; };
    8.55 -		6406CEF01CE3835300C14D77 /* per_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEB21CE3835300C14D77 /* per_encoder.h */; };
    8.56 -		6406CEF11CE3835300C14D77 /* per_opentype.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEB31CE3835300C14D77 /* per_opentype.c */; };
    8.57 -		6406CEF21CE3835300C14D77 /* per_opentype.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEB41CE3835300C14D77 /* per_opentype.h */; };
    8.58 -		6406CEF31CE3835300C14D77 /* per_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEB51CE3835300C14D77 /* per_support.c */; };
    8.59 -		6406CEF41CE3835300C14D77 /* per_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEB61CE3835300C14D77 /* per_support.h */; };
    8.60 -		6406CEF51CE3835300C14D77 /* PrintableString.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEB71CE3835300C14D77 /* PrintableString.c */; };
    8.61 -		6406CEF61CE3835300C14D77 /* PrintableString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEB81CE3835300C14D77 /* PrintableString.h */; };
    8.62 -		6406CEF91CE3835300C14D77 /* UTF8String.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEBB1CE3835300C14D77 /* UTF8String.c */; };
    8.63 -		6406CEFA1CE3835300C14D77 /* UTF8String.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEBC1CE3835300C14D77 /* UTF8String.h */; };
    8.64 -		6406CEFB1CE3835300C14D77 /* Version.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEBD1CE3835300C14D77 /* Version.c */; };
    8.65 -		6406CEFC1CE3835300C14D77 /* Version.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEBE1CE3835300C14D77 /* Version.h */; };
    8.66 -		6406CEFD1CE3835300C14D77 /* xer_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEBF1CE3835300C14D77 /* xer_decoder.c */; };
    8.67 -		6406CEFE1CE3835300C14D77 /* xer_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEC01CE3835300C14D77 /* xer_decoder.h */; };
    8.68 -		6406CEFF1CE3835300C14D77 /* xer_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEC11CE3835300C14D77 /* xer_encoder.c */; };
    8.69 -		6406CF001CE3835300C14D77 /* xer_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEC21CE3835300C14D77 /* xer_encoder.h */; };
    8.70 -		6406CF011CE3835300C14D77 /* xer_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 6406CEC31CE3835300C14D77 /* xer_support.c */; };
    8.71 -		6406CF021CE3835300C14D77 /* xer_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 6406CEC41CE3835300C14D77 /* xer_support.h */; };
    8.72  		644297C51BE11CE0002BC73B /* system.db in Resources */ = {isa = PBXBuildFile; fileRef = 64951A1B1BE0FCD800B10E71 /* system.db */; };
    8.73  		6467888C1CEB3D120001F54C /* map_asn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 646788871CEB3D120001F54C /* map_asn1.c */; };
    8.74  		6467888D1CEB3D120001F54C /* map_asn1.h in Headers */ = {isa = PBXBuildFile; fileRef = 646788881CEB3D120001F54C /* map_asn1.h */; };
    8.75 -		6467888E1CEB3D120001F54C /* sync_actions.c in Sources */ = {isa = PBXBuildFile; fileRef = 646788891CEB3D120001F54C /* sync_actions.c */; };
    8.76 -		6467888F1CEB3D120001F54C /* sync_driver.c in Sources */ = {isa = PBXBuildFile; fileRef = 6467888A1CEB3D120001F54C /* sync_driver.c */; };
    8.77 -		646788901CEB3D120001F54C /* sync_fsm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6467888B1CEB3D120001F54C /* sync_fsm.h */; };
    8.78 +		646C40EA1D510CD800C63EFF /* asn_application.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40951D510CD700C63EFF /* asn_application.h */; };
    8.79 +		646C40EB1D510CD800C63EFF /* asn_codecs_prim.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40961D510CD700C63EFF /* asn_codecs_prim.c */; };
    8.80 +		646C40EC1D510CD800C63EFF /* asn_codecs_prim.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40971D510CD700C63EFF /* asn_codecs_prim.h */; };
    8.81 +		646C40ED1D510CD800C63EFF /* asn_codecs.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40981D510CD700C63EFF /* asn_codecs.h */; };
    8.82 +		646C40EE1D510CD800C63EFF /* asn_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40991D510CD700C63EFF /* asn_internal.h */; };
    8.83 +		646C40EF1D510CD800C63EFF /* asn_SEQUENCE_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C409A1D510CD700C63EFF /* asn_SEQUENCE_OF.c */; };
    8.84 +		646C40F01D510CD800C63EFF /* asn_SEQUENCE_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C409B1D510CD700C63EFF /* asn_SEQUENCE_OF.h */; };
    8.85 +		646C40F11D510CD800C63EFF /* asn_SET_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C409C1D510CD700C63EFF /* asn_SET_OF.c */; };
    8.86 +		646C40F21D510CD800C63EFF /* asn_SET_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C409D1D510CD700C63EFF /* asn_SET_OF.h */; };
    8.87 +		646C40F31D510CD800C63EFF /* asn_system.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C409E1D510CD700C63EFF /* asn_system.h */; };
    8.88 +		646C40F41D510CD800C63EFF /* Beacon.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C409F1D510CD700C63EFF /* Beacon.c */; };
    8.89 +		646C40F51D510CD800C63EFF /* Beacon.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40A01D510CD700C63EFF /* Beacon.h */; };
    8.90 +		646C40F61D510CD800C63EFF /* ber_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40A11D510CD700C63EFF /* ber_decoder.c */; };
    8.91 +		646C40F71D510CD800C63EFF /* ber_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40A21D510CD700C63EFF /* ber_decoder.h */; };
    8.92 +		646C40F81D510CD800C63EFF /* ber_tlv_length.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40A31D510CD700C63EFF /* ber_tlv_length.c */; };
    8.93 +		646C40F91D510CD800C63EFF /* ber_tlv_length.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40A41D510CD700C63EFF /* ber_tlv_length.h */; };
    8.94 +		646C40FA1D510CD800C63EFF /* ber_tlv_tag.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40A51D510CD700C63EFF /* ber_tlv_tag.c */; };
    8.95 +		646C40FB1D510CD800C63EFF /* ber_tlv_tag.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40A61D510CD700C63EFF /* ber_tlv_tag.h */; };
    8.96 +		646C40FC1D510CD800C63EFF /* BIT_STRING.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40A71D510CD700C63EFF /* BIT_STRING.c */; };
    8.97 +		646C40FD1D510CD800C63EFF /* BIT_STRING.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40A81D510CD700C63EFF /* BIT_STRING.h */; };
    8.98 +		646C40FE1D510CD800C63EFF /* BOOLEAN.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40A91D510CD700C63EFF /* BOOLEAN.c */; };
    8.99 +		646C40FF1D510CD800C63EFF /* BOOLEAN.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40AA1D510CD700C63EFF /* BOOLEAN.h */; };
   8.100 +		646C41001D510CD800C63EFF /* constr_CHOICE.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40AB1D510CD700C63EFF /* constr_CHOICE.c */; };
   8.101 +		646C41011D510CD800C63EFF /* constr_CHOICE.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40AC1D510CD700C63EFF /* constr_CHOICE.h */; };
   8.102 +		646C41021D510CD800C63EFF /* constr_SEQUENCE_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40AD1D510CD700C63EFF /* constr_SEQUENCE_OF.c */; };
   8.103 +		646C41031D510CD800C63EFF /* constr_SEQUENCE_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40AE1D510CD700C63EFF /* constr_SEQUENCE_OF.h */; };
   8.104 +		646C41041D510CD800C63EFF /* constr_SEQUENCE.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40AF1D510CD700C63EFF /* constr_SEQUENCE.c */; };
   8.105 +		646C41051D510CD800C63EFF /* constr_SEQUENCE.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B01D510CD700C63EFF /* constr_SEQUENCE.h */; };
   8.106 +		646C41061D510CD800C63EFF /* constr_SET_OF.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B11D510CD700C63EFF /* constr_SET_OF.c */; };
   8.107 +		646C41071D510CD800C63EFF /* constr_SET_OF.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B21D510CD700C63EFF /* constr_SET_OF.h */; };
   8.108 +		646C41081D510CD800C63EFF /* constr_TYPE.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B31D510CD700C63EFF /* constr_TYPE.c */; };
   8.109 +		646C41091D510CD800C63EFF /* constr_TYPE.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B41D510CD700C63EFF /* constr_TYPE.h */; };
   8.110 +		646C410A1D510CD800C63EFF /* constraints.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B51D510CD700C63EFF /* constraints.c */; };
   8.111 +		646C410B1D510CD800C63EFF /* constraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B61D510CD700C63EFF /* constraints.h */; };
   8.112 +		646C410C1D510CD800C63EFF /* der_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B71D510CD700C63EFF /* der_encoder.c */; };
   8.113 +		646C410D1D510CD800C63EFF /* der_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B81D510CD700C63EFF /* der_encoder.h */; };
   8.114 +		646C410E1D510CD800C63EFF /* DeviceGroup-Protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */; };
   8.115 +		646C410F1D510CD800C63EFF /* DeviceGroup-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */; };
   8.116 +		646C41101D510CD800C63EFF /* GroupKeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40BB1D510CD700C63EFF /* GroupKeys.c */; };
   8.117 +		646C41111D510CD800C63EFF /* GroupKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40BC1D510CD700C63EFF /* GroupKeys.h */; };
   8.118 +		646C41121D510CD800C63EFF /* HandshakeRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40BD1D510CD700C63EFF /* HandshakeRequest.c */; };
   8.119 +		646C41131D510CD800C63EFF /* HandshakeRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40BE1D510CD700C63EFF /* HandshakeRequest.h */; };
   8.120 +		646C41141D510CD800C63EFF /* Hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40BF1D510CD700C63EFF /* Hash.c */; };
   8.121 +		646C41151D510CD800C63EFF /* Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40C01D510CD700C63EFF /* Hash.h */; };
   8.122 +		646C41181D510CD800C63EFF /* Hex.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40C31D510CD700C63EFF /* Hex.c */; };
   8.123 +		646C41191D510CD800C63EFF /* Hex.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40C41D510CD700C63EFF /* Hex.h */; };
   8.124 +		646C411A1D510CD800C63EFF /* Identity.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40C51D510CD700C63EFF /* Identity.c */; };
   8.125 +		646C411B1D510CD800C63EFF /* Identity.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40C61D510CD700C63EFF /* Identity.h */; };
   8.126 +		646C411C1D510CD800C63EFF /* IdentityList.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40C71D510CD700C63EFF /* IdentityList.c */; };
   8.127 +		646C411D1D510CD800C63EFF /* IdentityList.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40C81D510CD800C63EFF /* IdentityList.h */; };
   8.128 +		646C411E1D510CD800C63EFF /* INTEGER.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40C91D510CD800C63EFF /* INTEGER.c */; };
   8.129 +		646C411F1D510CD800C63EFF /* INTEGER.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40CA1D510CD800C63EFF /* INTEGER.h */; };
   8.130 +		646C41201D510CD800C63EFF /* ISO639-1.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40CB1D510CD800C63EFF /* ISO639-1.c */; };
   8.131 +		646C41211D510CD800C63EFF /* ISO639-1.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40CC1D510CD800C63EFF /* ISO639-1.h */; };
   8.132 +		646C41221D510CD800C63EFF /* NativeEnumerated.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40CD1D510CD800C63EFF /* NativeEnumerated.c */; };
   8.133 +		646C41231D510CD800C63EFF /* NativeEnumerated.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40CE1D510CD800C63EFF /* NativeEnumerated.h */; };
   8.134 +		646C41241D510CD800C63EFF /* NativeInteger.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40CF1D510CD800C63EFF /* NativeInteger.c */; };
   8.135 +		646C41251D510CD800C63EFF /* NativeInteger.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40D01D510CD800C63EFF /* NativeInteger.h */; };
   8.136 +		646C41261D510CD800C63EFF /* OCTET_STRING.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40D11D510CD800C63EFF /* OCTET_STRING.c */; };
   8.137 +		646C41271D510CD800C63EFF /* OCTET_STRING.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40D21D510CD800C63EFF /* OCTET_STRING.h */; };
   8.138 +		646C41281D510CD800C63EFF /* per_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40D31D510CD800C63EFF /* per_decoder.c */; };
   8.139 +		646C41291D510CD800C63EFF /* per_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40D41D510CD800C63EFF /* per_decoder.h */; };
   8.140 +		646C412A1D510CD800C63EFF /* per_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40D51D510CD800C63EFF /* per_encoder.c */; };
   8.141 +		646C412B1D510CD800C63EFF /* per_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40D61D510CD800C63EFF /* per_encoder.h */; };
   8.142 +		646C412C1D510CD800C63EFF /* per_opentype.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40D71D510CD800C63EFF /* per_opentype.c */; };
   8.143 +		646C412D1D510CD800C63EFF /* per_opentype.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40D81D510CD800C63EFF /* per_opentype.h */; };
   8.144 +		646C412E1D510CD800C63EFF /* per_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40D91D510CD800C63EFF /* per_support.c */; };
   8.145 +		646C412F1D510CD800C63EFF /* per_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DA1D510CD800C63EFF /* per_support.h */; };
   8.146 +		646C41301D510CD800C63EFF /* PrintableString.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40DB1D510CD800C63EFF /* PrintableString.c */; };
   8.147 +		646C41311D510CD800C63EFF /* PrintableString.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DC1D510CD800C63EFF /* PrintableString.h */; };
   8.148 +		646C41321D510CD800C63EFF /* Sync-Protocols.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40DE1D510CD800C63EFF /* Sync-Protocols.c */; };
   8.149 +		646C41331D510CD800C63EFF /* Sync-Protocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DF1D510CD800C63EFF /* Sync-Protocols.h */; };
   8.150 +		646C41341D510CD800C63EFF /* UTF8String.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E01D510CD800C63EFF /* UTF8String.c */; };
   8.151 +		646C41351D510CD800C63EFF /* UTF8String.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E11D510CD800C63EFF /* UTF8String.h */; };
   8.152 +		646C41361D510CD800C63EFF /* Version.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E21D510CD800C63EFF /* Version.c */; };
   8.153 +		646C41371D510CD800C63EFF /* Version.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E31D510CD800C63EFF /* Version.h */; };
   8.154 +		646C41381D510CD800C63EFF /* xer_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E41D510CD800C63EFF /* xer_decoder.c */; };
   8.155 +		646C41391D510CD800C63EFF /* xer_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E51D510CD800C63EFF /* xer_decoder.h */; };
   8.156 +		646C413A1D510CD800C63EFF /* xer_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E61D510CD800C63EFF /* xer_encoder.c */; };
   8.157 +		646C413B1D510CD800C63EFF /* xer_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E71D510CD800C63EFF /* xer_encoder.h */; };
   8.158 +		646C413C1D510CD800C63EFF /* xer_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E81D510CD800C63EFF /* xer_support.c */; };
   8.159 +		646C413D1D510CD800C63EFF /* xer_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E91D510CD800C63EFF /* xer_support.h */; };
   8.160 +		646C41451D510D2C00C63EFF /* sync_actions.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C413E1D510D2C00C63EFF /* sync_actions.c */; };
   8.161 +		646C41461D510D2C00C63EFF /* sync_driver.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C413F1D510D2C00C63EFF /* sync_driver.c */; };
   8.162 +		646C41471D510D2C00C63EFF /* sync_fsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41401D510D2C00C63EFF /* sync_fsm.c */; };
   8.163 +		646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C41411D510D2C00C63EFF /* sync_fsm.h */; };
   8.164 +		646C41491D510D2C00C63EFF /* sync_send_actions.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41421D510D2C00C63EFF /* sync_send_actions.c */; };
   8.165 +		646C414A1D510D2C00C63EFF /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41431D510D2C00C63EFF /* sync.c */; };
   8.166 +		646C414B1D510D2C00C63EFF /* sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C41441D510D2C00C63EFF /* sync.h */; };
   8.167 +		646C414E1D510D8800C63EFF /* baseprotocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C414C1D510D8800C63EFF /* baseprotocol.c */; };
   8.168 +		646C414F1D510D8800C63EFF /* baseprotocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C414D1D510D8800C63EFF /* baseprotocol.h */; };
   8.169  		649DE08B1B45C19100912F72 /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649DE08A1B45C19100912F72 /* libcurl.a */; };
   8.170  		64A826781B455D0800EECAF0 /* bloblist.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8264C1B455D0800EECAF0 /* bloblist.c */; };
   8.171  		64A826791B455D0800EECAF0 /* cryptotech.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8264E1B455D0800EECAF0 /* cryptotech.c */; };
   8.172 @@ -96,9 +127,6 @@
   8.173  		64A826891B455D0800EECAF0 /* trans_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826731B455D0800EECAF0 /* trans_auto.c */; };
   8.174  		64A8268A1B455D0800EECAF0 /* transport.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826751B455D0800EECAF0 /* transport.c */; };
   8.175  		64A8268C1B455D9D00EECAF0 /* pEpEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 64A826611B455D0800EECAF0 /* pEpEngine.h */; };
   8.176 -		64D2C8411CE2241C002CD757 /* sync_fsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 64D2C8401CE2241C002CD757 /* sync_fsm.c */; };
   8.177 -		64D2C84A1CE2245D002CD757 /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 64D2C8471CE2245D002CD757 /* sync.c */; };
   8.178 -		64D2C84B1CE2245D002CD757 /* sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 64D2C8481CE2245D002CD757 /* sync.h */; };
   8.179  /* End PBXBuildFile section */
   8.180  
   8.181  /* Begin PBXContainerItemProxy section */
   8.182 @@ -160,74 +188,105 @@
   8.183  
   8.184  /* Begin PBXFileReference section */
   8.185  		430D258A1C9ED75A00B94535 /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../src/blacklist.c; sourceTree = "<group>"; };
   8.186 -		6406CE861CE3835300C14D77 /* asn_application.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_application.h; path = ../asn.1/asn_application.h; sourceTree = "<group>"; };
   8.187 -		6406CE871CE3835300C14D77 /* asn_codecs_prim.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_codecs_prim.c; path = ../asn.1/asn_codecs_prim.c; sourceTree = "<group>"; };
   8.188 -		6406CE881CE3835300C14D77 /* asn_codecs_prim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_codecs_prim.h; path = ../asn.1/asn_codecs_prim.h; sourceTree = "<group>"; };
   8.189 -		6406CE891CE3835300C14D77 /* asn_codecs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_codecs.h; path = ../asn.1/asn_codecs.h; sourceTree = "<group>"; };
   8.190 -		6406CE8A1CE3835300C14D77 /* asn_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_internal.h; path = ../asn.1/asn_internal.h; sourceTree = "<group>"; };
   8.191 -		6406CE8B1CE3835300C14D77 /* asn_SEQUENCE_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_SEQUENCE_OF.c; path = ../asn.1/asn_SEQUENCE_OF.c; sourceTree = "<group>"; };
   8.192 -		6406CE8C1CE3835300C14D77 /* asn_SEQUENCE_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_SEQUENCE_OF.h; path = ../asn.1/asn_SEQUENCE_OF.h; sourceTree = "<group>"; };
   8.193 -		6406CE8D1CE3835300C14D77 /* asn_SET_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_SET_OF.c; path = ../asn.1/asn_SET_OF.c; sourceTree = "<group>"; };
   8.194 -		6406CE8E1CE3835300C14D77 /* asn_SET_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_SET_OF.h; path = ../asn.1/asn_SET_OF.h; sourceTree = "<group>"; };
   8.195 -		6406CE8F1CE3835300C14D77 /* asn_system.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_system.h; path = ../asn.1/asn_system.h; sourceTree = "<group>"; };
   8.196 -		6406CE901CE3835300C14D77 /* ber_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_decoder.c; path = ../asn.1/ber_decoder.c; sourceTree = "<group>"; };
   8.197 -		6406CE911CE3835300C14D77 /* ber_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_decoder.h; path = ../asn.1/ber_decoder.h; sourceTree = "<group>"; };
   8.198 -		6406CE921CE3835300C14D77 /* ber_tlv_length.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_tlv_length.c; path = ../asn.1/ber_tlv_length.c; sourceTree = "<group>"; };
   8.199 -		6406CE931CE3835300C14D77 /* ber_tlv_length.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_tlv_length.h; path = ../asn.1/ber_tlv_length.h; sourceTree = "<group>"; };
   8.200 -		6406CE941CE3835300C14D77 /* ber_tlv_tag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_tlv_tag.c; path = ../asn.1/ber_tlv_tag.c; sourceTree = "<group>"; };
   8.201 -		6406CE951CE3835300C14D77 /* ber_tlv_tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_tlv_tag.h; path = ../asn.1/ber_tlv_tag.h; sourceTree = "<group>"; };
   8.202 -		6406CE961CE3835300C14D77 /* BIT_STRING.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BIT_STRING.c; path = ../asn.1/BIT_STRING.c; sourceTree = "<group>"; };
   8.203 -		6406CE971CE3835300C14D77 /* BIT_STRING.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BIT_STRING.h; path = ../asn.1/BIT_STRING.h; sourceTree = "<group>"; };
   8.204 -		6406CE981CE3835300C14D77 /* constr_SEQUENCE_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SEQUENCE_OF.c; path = ../asn.1/constr_SEQUENCE_OF.c; sourceTree = "<group>"; };
   8.205 -		6406CE991CE3835300C14D77 /* constr_SEQUENCE_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SEQUENCE_OF.h; path = ../asn.1/constr_SEQUENCE_OF.h; sourceTree = "<group>"; };
   8.206 -		6406CE9A1CE3835300C14D77 /* constr_SEQUENCE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SEQUENCE.c; path = ../asn.1/constr_SEQUENCE.c; sourceTree = "<group>"; };
   8.207 -		6406CE9B1CE3835300C14D77 /* constr_SEQUENCE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SEQUENCE.h; path = ../asn.1/constr_SEQUENCE.h; sourceTree = "<group>"; };
   8.208 -		6406CE9C1CE3835300C14D77 /* constr_SET_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SET_OF.c; path = ../asn.1/constr_SET_OF.c; sourceTree = "<group>"; };
   8.209 -		6406CE9D1CE3835300C14D77 /* constr_SET_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SET_OF.h; path = ../asn.1/constr_SET_OF.h; sourceTree = "<group>"; };
   8.210 -		6406CE9E1CE3835300C14D77 /* constr_TYPE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_TYPE.c; path = ../asn.1/constr_TYPE.c; sourceTree = "<group>"; };
   8.211 -		6406CE9F1CE3835300C14D77 /* constr_TYPE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_TYPE.h; path = ../asn.1/constr_TYPE.h; sourceTree = "<group>"; };
   8.212 -		6406CEA01CE3835300C14D77 /* constraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constraints.c; path = ../asn.1/constraints.c; sourceTree = "<group>"; };
   8.213 -		6406CEA11CE3835300C14D77 /* constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constraints.h; path = ../asn.1/constraints.h; sourceTree = "<group>"; };
   8.214 -		6406CEA21CE3835300C14D77 /* der_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_encoder.c; path = ../asn.1/der_encoder.c; sourceTree = "<group>"; };
   8.215 -		6406CEA31CE3835300C14D77 /* der_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_encoder.h; path = ../asn.1/der_encoder.h; sourceTree = "<group>"; };
   8.216 -		6406CEA41CE3835300C14D77 /* Identity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Identity.c; path = ../asn.1/Identity.c; sourceTree = "<group>"; };
   8.217 -		6406CEA51CE3835300C14D77 /* Identity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Identity.h; path = ../asn.1/Identity.h; sourceTree = "<group>"; };
   8.218 -		6406CEA61CE3835300C14D77 /* INTEGER.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = INTEGER.c; path = ../asn.1/INTEGER.c; sourceTree = "<group>"; };
   8.219 -		6406CEA71CE3835300C14D77 /* INTEGER.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = INTEGER.h; path = ../asn.1/INTEGER.h; sourceTree = "<group>"; };
   8.220 -		6406CEA81CE3835300C14D77 /* Makefile.am.sample */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Makefile.am.sample; path = ../asn.1/Makefile.am.sample; sourceTree = "<group>"; };
   8.221 -		6406CEA91CE3835300C14D77 /* NativeEnumerated.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NativeEnumerated.c; path = ../asn.1/NativeEnumerated.c; sourceTree = "<group>"; };
   8.222 -		6406CEAA1CE3835300C14D77 /* NativeEnumerated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeEnumerated.h; path = ../asn.1/NativeEnumerated.h; sourceTree = "<group>"; };
   8.223 -		6406CEAB1CE3835300C14D77 /* NativeInteger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NativeInteger.c; path = ../asn.1/NativeInteger.c; sourceTree = "<group>"; };
   8.224 -		6406CEAC1CE3835300C14D77 /* NativeInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeInteger.h; path = ../asn.1/NativeInteger.h; sourceTree = "<group>"; };
   8.225 -		6406CEAD1CE3835300C14D77 /* OCTET_STRING.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OCTET_STRING.c; path = ../asn.1/OCTET_STRING.c; sourceTree = "<group>"; };
   8.226 -		6406CEAE1CE3835300C14D77 /* OCTET_STRING.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OCTET_STRING.h; path = ../asn.1/OCTET_STRING.h; sourceTree = "<group>"; };
   8.227 -		6406CEAF1CE3835300C14D77 /* per_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_decoder.c; path = ../asn.1/per_decoder.c; sourceTree = "<group>"; };
   8.228 -		6406CEB01CE3835300C14D77 /* per_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_decoder.h; path = ../asn.1/per_decoder.h; sourceTree = "<group>"; };
   8.229 -		6406CEB11CE3835300C14D77 /* per_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_encoder.c; path = ../asn.1/per_encoder.c; sourceTree = "<group>"; };
   8.230 -		6406CEB21CE3835300C14D77 /* per_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_encoder.h; path = ../asn.1/per_encoder.h; sourceTree = "<group>"; };
   8.231 -		6406CEB31CE3835300C14D77 /* per_opentype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_opentype.c; path = ../asn.1/per_opentype.c; sourceTree = "<group>"; };
   8.232 -		6406CEB41CE3835300C14D77 /* per_opentype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_opentype.h; path = ../asn.1/per_opentype.h; sourceTree = "<group>"; };
   8.233 -		6406CEB51CE3835300C14D77 /* per_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_support.c; path = ../asn.1/per_support.c; sourceTree = "<group>"; };
   8.234 -		6406CEB61CE3835300C14D77 /* per_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_support.h; path = ../asn.1/per_support.h; sourceTree = "<group>"; };
   8.235 -		6406CEB71CE3835300C14D77 /* PrintableString.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PrintableString.c; path = ../asn.1/PrintableString.c; sourceTree = "<group>"; };
   8.236 -		6406CEB81CE3835300C14D77 /* PrintableString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrintableString.h; path = ../asn.1/PrintableString.h; sourceTree = "<group>"; };
   8.237 -		6406CEBB1CE3835300C14D77 /* UTF8String.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = UTF8String.c; path = ../asn.1/UTF8String.c; sourceTree = "<group>"; };
   8.238 -		6406CEBC1CE3835300C14D77 /* UTF8String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UTF8String.h; path = ../asn.1/UTF8String.h; sourceTree = "<group>"; };
   8.239 -		6406CEBD1CE3835300C14D77 /* Version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Version.c; path = ../asn.1/Version.c; sourceTree = "<group>"; };
   8.240 -		6406CEBE1CE3835300C14D77 /* Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Version.h; path = ../asn.1/Version.h; sourceTree = "<group>"; };
   8.241 -		6406CEBF1CE3835300C14D77 /* xer_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_decoder.c; path = ../asn.1/xer_decoder.c; sourceTree = "<group>"; };
   8.242 -		6406CEC01CE3835300C14D77 /* xer_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_decoder.h; path = ../asn.1/xer_decoder.h; sourceTree = "<group>"; };
   8.243 -		6406CEC11CE3835300C14D77 /* xer_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_encoder.c; path = ../asn.1/xer_encoder.c; sourceTree = "<group>"; };
   8.244 -		6406CEC21CE3835300C14D77 /* xer_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_encoder.h; path = ../asn.1/xer_encoder.h; sourceTree = "<group>"; };
   8.245 -		6406CEC31CE3835300C14D77 /* xer_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_support.c; path = ../asn.1/xer_support.c; sourceTree = "<group>"; };
   8.246 -		6406CEC41CE3835300C14D77 /* xer_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_support.h; path = ../asn.1/xer_support.h; sourceTree = "<group>"; };
   8.247 +		4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
   8.248 +		4354FF681D6EE1A70033069C /* NULL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NULL.c; path = ../asn.1/NULL.c; sourceTree = "<group>"; };
   8.249 +		43BA0F451D7964750059172F /* asn1_helper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn1_helper.c; path = ../src/asn1_helper.c; sourceTree = "<group>"; };
   8.250  		644297BF1BE11C65002BC73B /* pEpTrustWords.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = pEpTrustWords.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
   8.251  		644297C11BE11C65002BC73B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
   8.252  		646788871CEB3D120001F54C /* map_asn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = map_asn1.c; path = ../src/map_asn1.c; sourceTree = "<group>"; };
   8.253  		646788881CEB3D120001F54C /* map_asn1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = map_asn1.h; path = ../src/map_asn1.h; sourceTree = "<group>"; };
   8.254 -		646788891CEB3D120001F54C /* sync_actions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_actions.c; path = ../src/sync_actions.c; sourceTree = "<group>"; };
   8.255 -		6467888A1CEB3D120001F54C /* sync_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_driver.c; path = ../src/sync_driver.c; sourceTree = "<group>"; };
   8.256 -		6467888B1CEB3D120001F54C /* sync_fsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync_fsm.h; path = ../src/sync_fsm.h; sourceTree = "<group>"; };
   8.257 +		646C40951D510CD700C63EFF /* asn_application.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_application.h; path = ../asn.1/asn_application.h; sourceTree = "<group>"; };
   8.258 +		646C40961D510CD700C63EFF /* asn_codecs_prim.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_codecs_prim.c; path = ../asn.1/asn_codecs_prim.c; sourceTree = "<group>"; };
   8.259 +		646C40971D510CD700C63EFF /* asn_codecs_prim.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_codecs_prim.h; path = ../asn.1/asn_codecs_prim.h; sourceTree = "<group>"; };
   8.260 +		646C40981D510CD700C63EFF /* asn_codecs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_codecs.h; path = ../asn.1/asn_codecs.h; sourceTree = "<group>"; };
   8.261 +		646C40991D510CD700C63EFF /* asn_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_internal.h; path = ../asn.1/asn_internal.h; sourceTree = "<group>"; };
   8.262 +		646C409A1D510CD700C63EFF /* asn_SEQUENCE_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_SEQUENCE_OF.c; path = ../asn.1/asn_SEQUENCE_OF.c; sourceTree = "<group>"; };
   8.263 +		646C409B1D510CD700C63EFF /* asn_SEQUENCE_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_SEQUENCE_OF.h; path = ../asn.1/asn_SEQUENCE_OF.h; sourceTree = "<group>"; };
   8.264 +		646C409C1D510CD700C63EFF /* asn_SET_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn_SET_OF.c; path = ../asn.1/asn_SET_OF.c; sourceTree = "<group>"; };
   8.265 +		646C409D1D510CD700C63EFF /* asn_SET_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_SET_OF.h; path = ../asn.1/asn_SET_OF.h; sourceTree = "<group>"; };
   8.266 +		646C409E1D510CD700C63EFF /* asn_system.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asn_system.h; path = ../asn.1/asn_system.h; sourceTree = "<group>"; };
   8.267 +		646C409F1D510CD700C63EFF /* Beacon.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Beacon.c; path = ../asn.1/Beacon.c; sourceTree = "<group>"; };
   8.268 +		646C40A01D510CD700C63EFF /* Beacon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Beacon.h; path = ../asn.1/Beacon.h; sourceTree = "<group>"; };
   8.269 +		646C40A11D510CD700C63EFF /* ber_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_decoder.c; path = ../asn.1/ber_decoder.c; sourceTree = "<group>"; };
   8.270 +		646C40A21D510CD700C63EFF /* ber_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_decoder.h; path = ../asn.1/ber_decoder.h; sourceTree = "<group>"; };
   8.271 +		646C40A31D510CD700C63EFF /* ber_tlv_length.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_tlv_length.c; path = ../asn.1/ber_tlv_length.c; sourceTree = "<group>"; };
   8.272 +		646C40A41D510CD700C63EFF /* ber_tlv_length.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_tlv_length.h; path = ../asn.1/ber_tlv_length.h; sourceTree = "<group>"; };
   8.273 +		646C40A51D510CD700C63EFF /* ber_tlv_tag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ber_tlv_tag.c; path = ../asn.1/ber_tlv_tag.c; sourceTree = "<group>"; };
   8.274 +		646C40A61D510CD700C63EFF /* ber_tlv_tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ber_tlv_tag.h; path = ../asn.1/ber_tlv_tag.h; sourceTree = "<group>"; };
   8.275 +		646C40A71D510CD700C63EFF /* BIT_STRING.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BIT_STRING.c; path = ../asn.1/BIT_STRING.c; sourceTree = "<group>"; };
   8.276 +		646C40A81D510CD700C63EFF /* BIT_STRING.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BIT_STRING.h; path = ../asn.1/BIT_STRING.h; sourceTree = "<group>"; };
   8.277 +		646C40A91D510CD700C63EFF /* BOOLEAN.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = BOOLEAN.c; path = ../asn.1/BOOLEAN.c; sourceTree = "<group>"; };
   8.278 +		646C40AA1D510CD700C63EFF /* BOOLEAN.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BOOLEAN.h; path = ../asn.1/BOOLEAN.h; sourceTree = "<group>"; };
   8.279 +		646C40AB1D510CD700C63EFF /* constr_CHOICE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_CHOICE.c; path = ../asn.1/constr_CHOICE.c; sourceTree = "<group>"; };
   8.280 +		646C40AC1D510CD700C63EFF /* constr_CHOICE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_CHOICE.h; path = ../asn.1/constr_CHOICE.h; sourceTree = "<group>"; };
   8.281 +		646C40AD1D510CD700C63EFF /* constr_SEQUENCE_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SEQUENCE_OF.c; path = ../asn.1/constr_SEQUENCE_OF.c; sourceTree = "<group>"; };
   8.282 +		646C40AE1D510CD700C63EFF /* constr_SEQUENCE_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SEQUENCE_OF.h; path = ../asn.1/constr_SEQUENCE_OF.h; sourceTree = "<group>"; };
   8.283 +		646C40AF1D510CD700C63EFF /* constr_SEQUENCE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SEQUENCE.c; path = ../asn.1/constr_SEQUENCE.c; sourceTree = "<group>"; };
   8.284 +		646C40B01D510CD700C63EFF /* constr_SEQUENCE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SEQUENCE.h; path = ../asn.1/constr_SEQUENCE.h; sourceTree = "<group>"; };
   8.285 +		646C40B11D510CD700C63EFF /* constr_SET_OF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_SET_OF.c; path = ../asn.1/constr_SET_OF.c; sourceTree = "<group>"; };
   8.286 +		646C40B21D510CD700C63EFF /* constr_SET_OF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_SET_OF.h; path = ../asn.1/constr_SET_OF.h; sourceTree = "<group>"; };
   8.287 +		646C40B31D510CD700C63EFF /* constr_TYPE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constr_TYPE.c; path = ../asn.1/constr_TYPE.c; sourceTree = "<group>"; };
   8.288 +		646C40B41D510CD700C63EFF /* constr_TYPE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constr_TYPE.h; path = ../asn.1/constr_TYPE.h; sourceTree = "<group>"; };
   8.289 +		646C40B51D510CD700C63EFF /* constraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = constraints.c; path = ../asn.1/constraints.c; sourceTree = "<group>"; };
   8.290 +		646C40B61D510CD700C63EFF /* constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constraints.h; path = ../asn.1/constraints.h; sourceTree = "<group>"; };
   8.291 +		646C40B71D510CD700C63EFF /* der_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_encoder.c; path = ../asn.1/der_encoder.c; sourceTree = "<group>"; };
   8.292 +		646C40B81D510CD700C63EFF /* der_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_encoder.h; path = ../asn.1/der_encoder.h; sourceTree = "<group>"; };
   8.293 +		646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "DeviceGroup-Protocol.c"; path = "../asn.1/DeviceGroup-Protocol.c"; sourceTree = "<group>"; };
   8.294 +		646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "DeviceGroup-Protocol.h"; path = "../asn.1/DeviceGroup-Protocol.h"; sourceTree = "<group>"; };
   8.295 +		646C40BB1D510CD700C63EFF /* GroupKeys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupKeys.c; path = ../asn.1/GroupKeys.c; sourceTree = "<group>"; };
   8.296 +		646C40BC1D510CD700C63EFF /* GroupKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupKeys.h; path = ../asn.1/GroupKeys.h; sourceTree = "<group>"; };
   8.297 +		646C40BD1D510CD700C63EFF /* HandshakeRequest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = HandshakeRequest.c; path = ../asn.1/HandshakeRequest.c; sourceTree = "<group>"; };
   8.298 +		646C40BE1D510CD700C63EFF /* HandshakeRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HandshakeRequest.h; path = ../asn.1/HandshakeRequest.h; sourceTree = "<group>"; };
   8.299 +		646C40BF1D510CD700C63EFF /* Hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Hash.c; path = ../asn.1/Hash.c; sourceTree = "<group>"; };
   8.300 +		646C40C01D510CD700C63EFF /* Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hash.h; path = ../asn.1/Hash.h; sourceTree = "<group>"; };
   8.301 +		646C40C31D510CD700C63EFF /* Hex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Hex.c; path = ../asn.1/Hex.c; sourceTree = "<group>"; };
   8.302 +		646C40C41D510CD700C63EFF /* Hex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Hex.h; path = ../asn.1/Hex.h; sourceTree = "<group>"; };
   8.303 +		646C40C51D510CD700C63EFF /* Identity.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Identity.c; path = ../asn.1/Identity.c; sourceTree = "<group>"; };
   8.304 +		646C40C61D510CD700C63EFF /* Identity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Identity.h; path = ../asn.1/Identity.h; sourceTree = "<group>"; };
   8.305 +		646C40C71D510CD700C63EFF /* IdentityList.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IdentityList.c; path = ../asn.1/IdentityList.c; sourceTree = "<group>"; };
   8.306 +		646C40C81D510CD800C63EFF /* IdentityList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentityList.h; path = ../asn.1/IdentityList.h; sourceTree = "<group>"; };
   8.307 +		646C40C91D510CD800C63EFF /* INTEGER.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = INTEGER.c; path = ../asn.1/INTEGER.c; sourceTree = "<group>"; };
   8.308 +		646C40CA1D510CD800C63EFF /* INTEGER.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = INTEGER.h; path = ../asn.1/INTEGER.h; sourceTree = "<group>"; };
   8.309 +		646C40CB1D510CD800C63EFF /* ISO639-1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "ISO639-1.c"; path = "../asn.1/ISO639-1.c"; sourceTree = "<group>"; };
   8.310 +		646C40CC1D510CD800C63EFF /* ISO639-1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ISO639-1.h"; path = "../asn.1/ISO639-1.h"; sourceTree = "<group>"; };
   8.311 +		646C40CD1D510CD800C63EFF /* NativeEnumerated.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NativeEnumerated.c; path = ../asn.1/NativeEnumerated.c; sourceTree = "<group>"; };
   8.312 +		646C40CE1D510CD800C63EFF /* NativeEnumerated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeEnumerated.h; path = ../asn.1/NativeEnumerated.h; sourceTree = "<group>"; };
   8.313 +		646C40CF1D510CD800C63EFF /* NativeInteger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NativeInteger.c; path = ../asn.1/NativeInteger.c; sourceTree = "<group>"; };
   8.314 +		646C40D01D510CD800C63EFF /* NativeInteger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeInteger.h; path = ../asn.1/NativeInteger.h; sourceTree = "<group>"; };
   8.315 +		646C40D11D510CD800C63EFF /* OCTET_STRING.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OCTET_STRING.c; path = ../asn.1/OCTET_STRING.c; sourceTree = "<group>"; };
   8.316 +		646C40D21D510CD800C63EFF /* OCTET_STRING.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OCTET_STRING.h; path = ../asn.1/OCTET_STRING.h; sourceTree = "<group>"; };
   8.317 +		646C40D31D510CD800C63EFF /* per_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_decoder.c; path = ../asn.1/per_decoder.c; sourceTree = "<group>"; };
   8.318 +		646C40D41D510CD800C63EFF /* per_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_decoder.h; path = ../asn.1/per_decoder.h; sourceTree = "<group>"; };
   8.319 +		646C40D51D510CD800C63EFF /* per_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_encoder.c; path = ../asn.1/per_encoder.c; sourceTree = "<group>"; };
   8.320 +		646C40D61D510CD800C63EFF /* per_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_encoder.h; path = ../asn.1/per_encoder.h; sourceTree = "<group>"; };
   8.321 +		646C40D71D510CD800C63EFF /* per_opentype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_opentype.c; path = ../asn.1/per_opentype.c; sourceTree = "<group>"; };
   8.322 +		646C40D81D510CD800C63EFF /* per_opentype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_opentype.h; path = ../asn.1/per_opentype.h; sourceTree = "<group>"; };
   8.323 +		646C40D91D510CD800C63EFF /* per_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = per_support.c; path = ../asn.1/per_support.c; sourceTree = "<group>"; };
   8.324 +		646C40DA1D510CD800C63EFF /* per_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_support.h; path = ../asn.1/per_support.h; sourceTree = "<group>"; };
   8.325 +		646C40DB1D510CD800C63EFF /* PrintableString.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PrintableString.c; path = ../asn.1/PrintableString.c; sourceTree = "<group>"; };
   8.326 +		646C40DC1D510CD800C63EFF /* PrintableString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrintableString.h; path = ../asn.1/PrintableString.h; sourceTree = "<group>"; };
   8.327 +		646C40DD1D510CD800C63EFF /* protocols.asn1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = protocols.asn1; path = ../asn.1/protocols.asn1; sourceTree = "<group>"; };
   8.328 +		646C40DE1D510CD800C63EFF /* Sync-Protocols.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "Sync-Protocols.c"; path = "../asn.1/Sync-Protocols.c"; sourceTree = "<group>"; };
   8.329 +		646C40DF1D510CD800C63EFF /* Sync-Protocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Sync-Protocols.h"; path = "../asn.1/Sync-Protocols.h"; sourceTree = "<group>"; };
   8.330 +		646C40E01D510CD800C63EFF /* UTF8String.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = UTF8String.c; path = ../asn.1/UTF8String.c; sourceTree = "<group>"; };
   8.331 +		646C40E11D510CD800C63EFF /* UTF8String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UTF8String.h; path = ../asn.1/UTF8String.h; sourceTree = "<group>"; };
   8.332 +		646C40E21D510CD800C63EFF /* Version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Version.c; path = ../asn.1/Version.c; sourceTree = "<group>"; };
   8.333 +		646C40E31D510CD800C63EFF /* Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Version.h; path = ../asn.1/Version.h; sourceTree = "<group>"; };
   8.334 +		646C40E41D510CD800C63EFF /* xer_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_decoder.c; path = ../asn.1/xer_decoder.c; sourceTree = "<group>"; };
   8.335 +		646C40E51D510CD800C63EFF /* xer_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_decoder.h; path = ../asn.1/xer_decoder.h; sourceTree = "<group>"; };
   8.336 +		646C40E61D510CD800C63EFF /* xer_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_encoder.c; path = ../asn.1/xer_encoder.c; sourceTree = "<group>"; };
   8.337 +		646C40E71D510CD800C63EFF /* xer_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_encoder.h; path = ../asn.1/xer_encoder.h; sourceTree = "<group>"; };
   8.338 +		646C40E81D510CD800C63EFF /* xer_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_support.c; path = ../asn.1/xer_support.c; sourceTree = "<group>"; };
   8.339 +		646C40E91D510CD800C63EFF /* xer_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_support.h; path = ../asn.1/xer_support.h; sourceTree = "<group>"; };
   8.340 +		646C413E1D510D2C00C63EFF /* sync_actions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_actions.c; path = ../src/sync_actions.c; sourceTree = "<group>"; };
   8.341 +		646C413F1D510D2C00C63EFF /* sync_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_driver.c; path = ../src/sync_driver.c; sourceTree = "<group>"; };
   8.342 +		646C41401D510D2C00C63EFF /* sync_fsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_fsm.c; path = ../src/sync_fsm.c; sourceTree = "<group>"; };
   8.343 +		646C41411D510D2C00C63EFF /* sync_fsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync_fsm.h; path = ../src/sync_fsm.h; sourceTree = "<group>"; };
   8.344 +		646C41421D510D2C00C63EFF /* sync_send_actions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_send_actions.c; path = ../src/sync_send_actions.c; sourceTree = "<group>"; };
   8.345 +		646C41431D510D2C00C63EFF /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = ../src/sync.c; sourceTree = "<group>"; };
   8.346 +		646C41441D510D2C00C63EFF /* sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync.h; path = ../src/sync.h; sourceTree = "<group>"; };
   8.347 +		646C414C1D510D8800C63EFF /* baseprotocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = baseprotocol.c; path = ../src/baseprotocol.c; sourceTree = "<group>"; };
   8.348 +		646C414D1D510D8800C63EFF /* baseprotocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = baseprotocol.h; path = ../src/baseprotocol.h; sourceTree = "<group>"; };
   8.349  		64796A3F1B455AA5004B1C24 /* libpEpEngine.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpEpEngine.a; sourceTree = BUILT_PRODUCTS_DIR; };
   8.350  		64951A1B1BE0FCD800B10E71 /* system.db */ = {isa = PBXFileReference; lastKnownFileType = file; name = system.db; path = ../db/system.db; sourceTree = "<group>"; };
   8.351  		649DE08A1B45C19100912F72 /* libcurl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libcurl.a; sourceTree = "<group>"; };
   8.352 @@ -273,9 +332,6 @@
   8.353  		64A826751B455D0800EECAF0 /* transport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = transport.c; path = ../src/transport.c; sourceTree = "<group>"; };
   8.354  		64A826761B455D0800EECAF0 /* transport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = transport.h; path = ../src/transport.h; sourceTree = "<group>"; };
   8.355  		64A826771B455D0800EECAF0 /* wrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wrappers.h; path = ../src/wrappers.h; sourceTree = "<group>"; };
   8.356 -		64D2C8401CE2241C002CD757 /* sync_fsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_fsm.c; path = ../src/sync_fsm.c; sourceTree = "<group>"; };
   8.357 -		64D2C8471CE2245D002CD757 /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = ../src/sync.c; sourceTree = "<group>"; };
   8.358 -		64D2C8481CE2245D002CD757 /* sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync.h; path = ../src/sync.h; sourceTree = "<group>"; };
   8.359  		64DA240C1B832EA0000BEE80 /* netpgp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = netpgp.xcodeproj; path = "../../netpgp-et/netpgp-xcode/netpgp.xcodeproj"; sourceTree = "<group>"; };
   8.360  		64DA24121B832EBA000BEE80 /* libetpan.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libetpan.xcodeproj; path = "../../libetpan/build-mac/libetpan.xcodeproj"; sourceTree = "<group>"; };
   8.361  /* End PBXFileReference section */
   8.362 @@ -304,67 +360,90 @@
   8.363  		6406CE811CE382F400C14D77 /* asn.1 */ = {
   8.364  			isa = PBXGroup;
   8.365  			children = (
   8.366 -				6406CE861CE3835300C14D77 /* asn_application.h */,
   8.367 -				6406CE871CE3835300C14D77 /* asn_codecs_prim.c */,
   8.368 -				6406CE881CE3835300C14D77 /* asn_codecs_prim.h */,
   8.369 -				6406CE891CE3835300C14D77 /* asn_codecs.h */,
   8.370 -				6406CE8A1CE3835300C14D77 /* asn_internal.h */,
   8.371 -				6406CE8B1CE3835300C14D77 /* asn_SEQUENCE_OF.c */,
   8.372 -				6406CE8C1CE3835300C14D77 /* asn_SEQUENCE_OF.h */,
   8.373 -				6406CE8D1CE3835300C14D77 /* asn_SET_OF.c */,
   8.374 -				6406CE8E1CE3835300C14D77 /* asn_SET_OF.h */,
   8.375 -				6406CE8F1CE3835300C14D77 /* asn_system.h */,
   8.376 -				6406CE901CE3835300C14D77 /* ber_decoder.c */,
   8.377 -				6406CE911CE3835300C14D77 /* ber_decoder.h */,
   8.378 -				6406CE921CE3835300C14D77 /* ber_tlv_length.c */,
   8.379 -				6406CE931CE3835300C14D77 /* ber_tlv_length.h */,
   8.380 -				6406CE941CE3835300C14D77 /* ber_tlv_tag.c */,
   8.381 -				6406CE951CE3835300C14D77 /* ber_tlv_tag.h */,
   8.382 -				6406CE961CE3835300C14D77 /* BIT_STRING.c */,
   8.383 -				6406CE971CE3835300C14D77 /* BIT_STRING.h */,
   8.384 -				6406CE981CE3835300C14D77 /* constr_SEQUENCE_OF.c */,
   8.385 -				6406CE991CE3835300C14D77 /* constr_SEQUENCE_OF.h */,
   8.386 -				6406CE9A1CE3835300C14D77 /* constr_SEQUENCE.c */,
   8.387 -				6406CE9B1CE3835300C14D77 /* constr_SEQUENCE.h */,
   8.388 -				6406CE9C1CE3835300C14D77 /* constr_SET_OF.c */,
   8.389 -				6406CE9D1CE3835300C14D77 /* constr_SET_OF.h */,
   8.390 -				6406CE9E1CE3835300C14D77 /* constr_TYPE.c */,
   8.391 -				6406CE9F1CE3835300C14D77 /* constr_TYPE.h */,
   8.392 -				6406CEA01CE3835300C14D77 /* constraints.c */,
   8.393 -				6406CEA11CE3835300C14D77 /* constraints.h */,
   8.394 -				6406CEA21CE3835300C14D77 /* der_encoder.c */,
   8.395 -				6406CEA31CE3835300C14D77 /* der_encoder.h */,
   8.396 -				6406CEA41CE3835300C14D77 /* Identity.c */,
   8.397 -				6406CEA51CE3835300C14D77 /* Identity.h */,
   8.398 -				6406CEA61CE3835300C14D77 /* INTEGER.c */,
   8.399 -				6406CEA71CE3835300C14D77 /* INTEGER.h */,
   8.400 -				6406CEA81CE3835300C14D77 /* Makefile.am.sample */,
   8.401 -				6406CEA91CE3835300C14D77 /* NativeEnumerated.c */,
   8.402 -				6406CEAA1CE3835300C14D77 /* NativeEnumerated.h */,
   8.403 -				6406CEAB1CE3835300C14D77 /* NativeInteger.c */,
   8.404 -				6406CEAC1CE3835300C14D77 /* NativeInteger.h */,
   8.405 -				6406CEAD1CE3835300C14D77 /* OCTET_STRING.c */,
   8.406 -				6406CEAE1CE3835300C14D77 /* OCTET_STRING.h */,
   8.407 -				6406CEAF1CE3835300C14D77 /* per_decoder.c */,
   8.408 -				6406CEB01CE3835300C14D77 /* per_decoder.h */,
   8.409 -				6406CEB11CE3835300C14D77 /* per_encoder.c */,
   8.410 -				6406CEB21CE3835300C14D77 /* per_encoder.h */,
   8.411 -				6406CEB31CE3835300C14D77 /* per_opentype.c */,
   8.412 -				6406CEB41CE3835300C14D77 /* per_opentype.h */,
   8.413 -				6406CEB51CE3835300C14D77 /* per_support.c */,
   8.414 -				6406CEB61CE3835300C14D77 /* per_support.h */,
   8.415 -				6406CEB71CE3835300C14D77 /* PrintableString.c */,
   8.416 -				6406CEB81CE3835300C14D77 /* PrintableString.h */,
   8.417 -				6406CEBB1CE3835300C14D77 /* UTF8String.c */,
   8.418 -				6406CEBC1CE3835300C14D77 /* UTF8String.h */,
   8.419 -				6406CEBD1CE3835300C14D77 /* Version.c */,
   8.420 -				6406CEBE1CE3835300C14D77 /* Version.h */,
   8.421 -				6406CEBF1CE3835300C14D77 /* xer_decoder.c */,
   8.422 -				6406CEC01CE3835300C14D77 /* xer_decoder.h */,
   8.423 -				6406CEC11CE3835300C14D77 /* xer_encoder.c */,
   8.424 -				6406CEC21CE3835300C14D77 /* xer_encoder.h */,
   8.425 -				6406CEC31CE3835300C14D77 /* xer_support.c */,
   8.426 -				6406CEC41CE3835300C14D77 /* xer_support.h */,
   8.427 +				4354FF681D6EE1A70033069C /* NULL.c */,
   8.428 +				646C40951D510CD700C63EFF /* asn_application.h */,
   8.429 +				646C40961D510CD700C63EFF /* asn_codecs_prim.c */,
   8.430 +				646C40971D510CD700C63EFF /* asn_codecs_prim.h */,
   8.431 +				646C40981D510CD700C63EFF /* asn_codecs.h */,
   8.432 +				646C40991D510CD700C63EFF /* asn_internal.h */,
   8.433 +				646C409A1D510CD700C63EFF /* asn_SEQUENCE_OF.c */,
   8.434 +				646C409B1D510CD700C63EFF /* asn_SEQUENCE_OF.h */,
   8.435 +				646C409C1D510CD700C63EFF /* asn_SET_OF.c */,
   8.436 +				646C409D1D510CD700C63EFF /* asn_SET_OF.h */,
   8.437 +				646C409E1D510CD700C63EFF /* asn_system.h */,
   8.438 +				646C409F1D510CD700C63EFF /* Beacon.c */,
   8.439 +				646C40A01D510CD700C63EFF /* Beacon.h */,
   8.440 +				646C40A11D510CD700C63EFF /* ber_decoder.c */,
   8.441 +				646C40A21D510CD700C63EFF /* ber_decoder.h */,
   8.442 +				646C40A31D510CD700C63EFF /* ber_tlv_length.c */,
   8.443 +				646C40A41D510CD700C63EFF /* ber_tlv_length.h */,
   8.444 +				646C40A51D510CD700C63EFF /* ber_tlv_tag.c */,
   8.445 +				646C40A61D510CD700C63EFF /* ber_tlv_tag.h */,
   8.446 +				646C40A71D510CD700C63EFF /* BIT_STRING.c */,
   8.447 +				646C40A81D510CD700C63EFF /* BIT_STRING.h */,
   8.448 +				646C40A91D510CD700C63EFF /* BOOLEAN.c */,
   8.449 +				646C40AA1D510CD700C63EFF /* BOOLEAN.h */,
   8.450 +				646C40AB1D510CD700C63EFF /* constr_CHOICE.c */,
   8.451 +				646C40AC1D510CD700C63EFF /* constr_CHOICE.h */,
   8.452 +				646C40AD1D510CD700C63EFF /* constr_SEQUENCE_OF.c */,
   8.453 +				646C40AE1D510CD700C63EFF /* constr_SEQUENCE_OF.h */,
   8.454 +				646C40AF1D510CD700C63EFF /* constr_SEQUENCE.c */,
   8.455 +				646C40B01D510CD700C63EFF /* constr_SEQUENCE.h */,
   8.456 +				646C40B11D510CD700C63EFF /* constr_SET_OF.c */,
   8.457 +				646C40B21D510CD700C63EFF /* constr_SET_OF.h */,
   8.458 +				646C40B31D510CD700C63EFF /* constr_TYPE.c */,
   8.459 +				646C40B41D510CD700C63EFF /* constr_TYPE.h */,
   8.460 +				646C40B51D510CD700C63EFF /* constraints.c */,
   8.461 +				646C40B61D510CD700C63EFF /* constraints.h */,
   8.462 +				646C40B71D510CD700C63EFF /* der_encoder.c */,
   8.463 +				646C40B81D510CD700C63EFF /* der_encoder.h */,
   8.464 +				646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */,
   8.465 +				646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */,
   8.466 +				646C40BB1D510CD700C63EFF /* GroupKeys.c */,
   8.467 +				646C40BC1D510CD700C63EFF /* GroupKeys.h */,
   8.468 +				646C40BD1D510CD700C63EFF /* HandshakeRequest.c */,
   8.469 +				646C40BE1D510CD700C63EFF /* HandshakeRequest.h */,
   8.470 +				646C40BF1D510CD700C63EFF /* Hash.c */,
   8.471 +				646C40C01D510CD700C63EFF /* Hash.h */,
   8.472 +				646C40C31D510CD700C63EFF /* Hex.c */,
   8.473 +				646C40C41D510CD700C63EFF /* Hex.h */,
   8.474 +				646C40C51D510CD700C63EFF /* Identity.c */,
   8.475 +				646C40C61D510CD700C63EFF /* Identity.h */,
   8.476 +				646C40C71D510CD700C63EFF /* IdentityList.c */,
   8.477 +				646C40C81D510CD800C63EFF /* IdentityList.h */,
   8.478 +				646C40C91D510CD800C63EFF /* INTEGER.c */,
   8.479 +				646C40CA1D510CD800C63EFF /* INTEGER.h */,
   8.480 +				646C40CB1D510CD800C63EFF /* ISO639-1.c */,
   8.481 +				646C40CC1D510CD800C63EFF /* ISO639-1.h */,
   8.482 +				646C40CD1D510CD800C63EFF /* NativeEnumerated.c */,
   8.483 +				646C40CE1D510CD800C63EFF /* NativeEnumerated.h */,
   8.484 +				646C40CF1D510CD800C63EFF /* NativeInteger.c */,
   8.485 +				646C40D01D510CD800C63EFF /* NativeInteger.h */,
   8.486 +				646C40D11D510CD800C63EFF /* OCTET_STRING.c */,
   8.487 +				646C40D21D510CD800C63EFF /* OCTET_STRING.h */,
   8.488 +				646C40D31D510CD800C63EFF /* per_decoder.c */,
   8.489 +				646C40D41D510CD800C63EFF /* per_decoder.h */,
   8.490 +				646C40D51D510CD800C63EFF /* per_encoder.c */,
   8.491 +				646C40D61D510CD800C63EFF /* per_encoder.h */,
   8.492 +				646C40D71D510CD800C63EFF /* per_opentype.c */,
   8.493 +				646C40D81D510CD800C63EFF /* per_opentype.h */,
   8.494 +				646C40D91D510CD800C63EFF /* per_support.c */,
   8.495 +				646C40DA1D510CD800C63EFF /* per_support.h */,
   8.496 +				646C40DB1D510CD800C63EFF /* PrintableString.c */,
   8.497 +				646C40DC1D510CD800C63EFF /* PrintableString.h */,
   8.498 +				646C40DD1D510CD800C63EFF /* protocols.asn1 */,
   8.499 +				646C40DE1D510CD800C63EFF /* Sync-Protocols.c */,
   8.500 +				646C40DF1D510CD800C63EFF /* Sync-Protocols.h */,
   8.501 +				646C40E01D510CD800C63EFF /* UTF8String.c */,
   8.502 +				646C40E11D510CD800C63EFF /* UTF8String.h */,
   8.503 +				646C40E21D510CD800C63EFF /* Version.c */,
   8.504 +				646C40E31D510CD800C63EFF /* Version.h */,
   8.505 +				646C40E41D510CD800C63EFF /* xer_decoder.c */,
   8.506 +				646C40E51D510CD800C63EFF /* xer_decoder.h */,
   8.507 +				646C40E61D510CD800C63EFF /* xer_encoder.c */,
   8.508 +				646C40E71D510CD800C63EFF /* xer_encoder.h */,
   8.509 +				646C40E81D510CD800C63EFF /* xer_support.c */,
   8.510 +				646C40E91D510CD800C63EFF /* xer_support.h */,
   8.511  			);
   8.512  			name = asn.1;
   8.513  			sourceTree = "<group>";
   8.514 @@ -421,14 +500,19 @@
   8.515  		64A8264B1B455C5600EECAF0 /* srcref */ = {
   8.516  			isa = PBXGroup;
   8.517  			children = (
   8.518 +				43BA0F451D7964750059172F /* asn1_helper.c */,
   8.519 +				4354FF641D6EDF300033069C /* sync_impl.c */,
   8.520 +				646C414C1D510D8800C63EFF /* baseprotocol.c */,
   8.521 +				646C414D1D510D8800C63EFF /* baseprotocol.h */,
   8.522 +				646C413E1D510D2C00C63EFF /* sync_actions.c */,
   8.523 +				646C413F1D510D2C00C63EFF /* sync_driver.c */,
   8.524 +				646C41401D510D2C00C63EFF /* sync_fsm.c */,
   8.525 +				646C41411D510D2C00C63EFF /* sync_fsm.h */,
   8.526 +				646C41421D510D2C00C63EFF /* sync_send_actions.c */,
   8.527 +				646C41431D510D2C00C63EFF /* sync.c */,
   8.528 +				646C41441D510D2C00C63EFF /* sync.h */,
   8.529  				646788871CEB3D120001F54C /* map_asn1.c */,
   8.530  				646788881CEB3D120001F54C /* map_asn1.h */,
   8.531 -				646788891CEB3D120001F54C /* sync_actions.c */,
   8.532 -				6467888A1CEB3D120001F54C /* sync_driver.c */,
   8.533 -				6467888B1CEB3D120001F54C /* sync_fsm.h */,
   8.534 -				64D2C8471CE2245D002CD757 /* sync.c */,
   8.535 -				64D2C8481CE2245D002CD757 /* sync.h */,
   8.536 -				64D2C8401CE2241C002CD757 /* sync_fsm.c */,
   8.537  				430D258A1C9ED75A00B94535 /* blacklist.c */,
   8.538  				64A8264C1B455D0800EECAF0 /* bloblist.c */,
   8.539  				64A8264D1B455D0800EECAF0 /* bloblist.h */,
   8.540 @@ -483,42 +567,54 @@
   8.541  			isa = PBXHeadersBuildPhase;
   8.542  			buildActionMask = 2147483647;
   8.543  			files = (
   8.544 -				6406CEFA1CE3835300C14D77 /* UTF8String.h in Headers */,
   8.545 -				6406CEF01CE3835300C14D77 /* per_encoder.h in Headers */,
   8.546 -				6406CEC81CE3835300C14D77 /* asn_codecs.h in Headers */,
   8.547 -				6406CEE21CE3835300C14D77 /* der_encoder.h in Headers */,
   8.548 -				6406CED01CE3835300C14D77 /* ber_decoder.h in Headers */,
   8.549 -				6406CF001CE3835300C14D77 /* xer_encoder.h in Headers */,
   8.550 +				646C41031D510CD800C63EFF /* constr_SEQUENCE_OF.h in Headers */,
   8.551 +				646C40ED1D510CD800C63EFF /* asn_codecs.h in Headers */,
   8.552 +				646C41371D510CD800C63EFF /* Version.h in Headers */,
   8.553 +				646C412F1D510CD800C63EFF /* per_support.h in Headers */,
   8.554 +				646C41111D510CD800C63EFF /* GroupKeys.h in Headers */,
   8.555 +				646C40F21D510CD800C63EFF /* asn_SET_OF.h in Headers */,
   8.556 +				646C41311D510CD800C63EFF /* PrintableString.h in Headers */,
   8.557 +				646C40F51D510CD800C63EFF /* Beacon.h in Headers */,
   8.558 +				646C40F71D510CD800C63EFF /* ber_decoder.h in Headers */,
   8.559 +				646C41351D510CD800C63EFF /* UTF8String.h in Headers */,
   8.560 +				646C40EC1D510CD800C63EFF /* asn_codecs_prim.h in Headers */,
   8.561 +				646C40EE1D510CD800C63EFF /* asn_internal.h in Headers */,
   8.562 +				646C413B1D510CD800C63EFF /* xer_encoder.h in Headers */,
   8.563 +				646C40F01D510CD800C63EFF /* asn_SEQUENCE_OF.h in Headers */,
   8.564 +				646C40FD1D510CD800C63EFF /* BIT_STRING.h in Headers */,
   8.565 +				646C411F1D510CD800C63EFF /* INTEGER.h in Headers */,
   8.566 +				646C411D1D510CD800C63EFF /* IdentityList.h in Headers */,
   8.567 +				646C41331D510CD800C63EFF /* Sync-Protocols.h in Headers */,
   8.568 +				646C41011D510CD800C63EFF /* constr_CHOICE.h in Headers */,
   8.569 +				646C40FB1D510CD800C63EFF /* ber_tlv_tag.h in Headers */,
   8.570 +				646C414F1D510D8800C63EFF /* baseprotocol.h in Headers */,
   8.571  				6467888D1CEB3D120001F54C /* map_asn1.h in Headers */,
   8.572 -				6406CEEC1CE3835300C14D77 /* OCTET_STRING.h in Headers */,
   8.573 -				6406CEC51CE3835300C14D77 /* asn_application.h in Headers */,
   8.574 -				6406CEFC1CE3835300C14D77 /* Version.h in Headers */,
   8.575 -				6406CEDC1CE3835300C14D77 /* constr_SET_OF.h in Headers */,
   8.576 -				6406CEC71CE3835300C14D77 /* asn_codecs_prim.h in Headers */,
   8.577 -				6406CED21CE3835300C14D77 /* ber_tlv_length.h in Headers */,
   8.578 -				6406CED41CE3835300C14D77 /* ber_tlv_tag.h in Headers */,
   8.579 -				6406CED61CE3835300C14D77 /* BIT_STRING.h in Headers */,
   8.580 -				6406CEE41CE3835300C14D77 /* Identity.h in Headers */,
   8.581 -				6406CEE01CE3835300C14D77 /* constraints.h in Headers */,
   8.582 -				6406CEDA1CE3835300C14D77 /* constr_SEQUENCE.h in Headers */,
   8.583 -				6406CF021CE3835300C14D77 /* xer_support.h in Headers */,
   8.584 -				6406CEC91CE3835300C14D77 /* asn_internal.h in Headers */,
   8.585 -				6406CECB1CE3835300C14D77 /* asn_SEQUENCE_OF.h in Headers */,
   8.586 -				6406CECE1CE3835300C14D77 /* asn_system.h in Headers */,
   8.587 -				646788901CEB3D120001F54C /* sync_fsm.h in Headers */,
   8.588 -				6406CEF21CE3835300C14D77 /* per_opentype.h in Headers */,
   8.589 -				6406CECD1CE3835300C14D77 /* asn_SET_OF.h in Headers */,
   8.590 -				64D2C84B1CE2245D002CD757 /* sync.h in Headers */,
   8.591 -				6406CEEA1CE3835300C14D77 /* NativeInteger.h in Headers */,
   8.592 -				6406CEFE1CE3835300C14D77 /* xer_decoder.h in Headers */,
   8.593 -				6406CEDE1CE3835300C14D77 /* constr_TYPE.h in Headers */,
   8.594 -				6406CEF41CE3835300C14D77 /* per_support.h in Headers */,
   8.595 -				6406CEEE1CE3835300C14D77 /* per_decoder.h in Headers */,
   8.596 +				646C41131D510CD800C63EFF /* HandshakeRequest.h in Headers */,
   8.597 +				646C40F31D510CD800C63EFF /* asn_system.h in Headers */,
   8.598 +				646C410B1D510CD800C63EFF /* constraints.h in Headers */,
   8.599 +				646C41251D510CD800C63EFF /* NativeInteger.h in Headers */,
   8.600 +				646C41271D510CD800C63EFF /* OCTET_STRING.h in Headers */,
   8.601 +				646C41391D510CD800C63EFF /* xer_decoder.h in Headers */,
   8.602 +				646C40EA1D510CD800C63EFF /* asn_application.h in Headers */,
   8.603 +				646C41211D510CD800C63EFF /* ISO639-1.h in Headers */,
   8.604 +				646C412D1D510CD800C63EFF /* per_opentype.h in Headers */,
   8.605 +				646C413D1D510CD800C63EFF /* xer_support.h in Headers */,
   8.606 +				646C41191D510CD800C63EFF /* Hex.h in Headers */,
   8.607 +				646C41051D510CD800C63EFF /* constr_SEQUENCE.h in Headers */,
   8.608 +				646C41151D510CD800C63EFF /* Hash.h in Headers */,
   8.609 +				646C410F1D510CD800C63EFF /* DeviceGroup-Protocol.h in Headers */,
   8.610 +				646C40FF1D510CD800C63EFF /* BOOLEAN.h in Headers */,
   8.611 +				646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */,
   8.612  				64A8268C1B455D9D00EECAF0 /* pEpEngine.h in Headers */,
   8.613 -				6406CED81CE3835300C14D77 /* constr_SEQUENCE_OF.h in Headers */,
   8.614 -				6406CEE81CE3835300C14D77 /* NativeEnumerated.h in Headers */,
   8.615 -				6406CEE61CE3835300C14D77 /* INTEGER.h in Headers */,
   8.616 -				6406CEF61CE3835300C14D77 /* PrintableString.h in Headers */,
   8.617 +				646C41091D510CD800C63EFF /* constr_TYPE.h in Headers */,
   8.618 +				646C410D1D510CD800C63EFF /* der_encoder.h in Headers */,
   8.619 +				646C41231D510CD800C63EFF /* NativeEnumerated.h in Headers */,
   8.620 +				646C41071D510CD800C63EFF /* constr_SET_OF.h in Headers */,
   8.621 +				646C414B1D510D2C00C63EFF /* sync.h in Headers */,
   8.622 +				646C411B1D510CD800C63EFF /* Identity.h in Headers */,
   8.623 +				646C412B1D510CD800C63EFF /* per_encoder.h in Headers */,
   8.624 +				646C40F91D510CD800C63EFF /* ber_tlv_length.h in Headers */,
   8.625 +				646C41291D510CD800C63EFF /* per_decoder.h in Headers */,
   8.626  			);
   8.627  			runOnlyForDeploymentPostprocessing = 0;
   8.628  		};
   8.629 @@ -677,7 +773,7 @@
   8.630  			);
   8.631  			runOnlyForDeploymentPostprocessing = 0;
   8.632  			shellPath = /bin/sh;
   8.633 -			shellScript = "mkdir -p \"$BUILT_PRODUCTS_DIR/include\"\n\ncp \"$SRCROOT/../src/\"{\\\npEpEngine.h,\\\ncryptotech.h,\\\nkeymanagement.h,\\\nmessage_api.h,\\\ndynamic_api.h,\\\nstringlist.h,\\\ntimestamp.h,\\\nidentity_list.h,\\\nbloblist.h,\\\nstringpair.h,\\\nmessage.h,\\\nmime.h} \"$BUILT_PRODUCTS_DIR/include\"\n\npushd ../asn.1\nmake generate\nmake\npopd";
   8.634 +			shellScript = "mkdir -p \"$BUILT_PRODUCTS_DIR/include\"\n\ncp \"$SRCROOT/../src/\"{\\\npEpEngine.h,\\\ncryptotech.h,\\\nkeymanagement.h,\\\nmessage_api.h,\\\ndynamic_api.h,\\\nstringlist.h,\\\ntimestamp.h,\\\nidentity_list.h,\\\nbloblist.h,\\\nstringpair.h,\\\nmessage.h,\\\nmime.h} \"$BUILT_PRODUCTS_DIR/include\"\n\nbash -l -c \"make -C ../asn.1 generate\"\nbash -l -c \"make -C ../asn.1\"\nbash -l -c \"LC_ALL=en_US.UTF-8 YML_PATH=$HOME/yml2 make -C ../sync\"\n";
   8.635  		};
   8.636  /* End PBXShellScriptBuildPhase section */
   8.637  
   8.638 @@ -694,57 +790,73 @@
   8.639  			buildActionMask = 2147483647;
   8.640  			files = (
   8.641  				64A826871B455D0800EECAF0 /* stringpair.c in Sources */,
   8.642 -				6406CEE91CE3835300C14D77 /* NativeInteger.c in Sources */,
   8.643 -				6467888F1CEB3D120001F54C /* sync_driver.c in Sources */,
   8.644 -				6406CEFD1CE3835300C14D77 /* xer_decoder.c in Sources */,
   8.645 -				6406CEFB1CE3835300C14D77 /* Version.c in Sources */,
   8.646 -				64D2C8411CE2241C002CD757 /* sync_fsm.c in Sources */,
   8.647 -				6406CEE31CE3835300C14D77 /* Identity.c in Sources */,
   8.648 +				646C41341D510CD800C63EFF /* UTF8String.c in Sources */,
   8.649  				64A826831B455D0800EECAF0 /* platform_unix.c in Sources */,
   8.650 -				6406CEE51CE3835300C14D77 /* INTEGER.c in Sources */,
   8.651 +				646C40F81D510CD800C63EFF /* ber_tlv_length.c in Sources */,
   8.652 +				646C411C1D510CD800C63EFF /* IdentityList.c in Sources */,
   8.653 +				646C41301D510CD800C63EFF /* PrintableString.c in Sources */,
   8.654  				64A8267B1B455D0800EECAF0 /* etpan_mime.c in Sources */,
   8.655 -				6406CECF1CE3835300C14D77 /* ber_decoder.c in Sources */,
   8.656  				64A8267A1B455D0800EECAF0 /* email.c in Sources */,
   8.657 -				6406CEDF1CE3835300C14D77 /* constraints.c in Sources */,
   8.658 +				646C41261D510CD800C63EFF /* OCTET_STRING.c in Sources */,
   8.659 +				646C41141D510CD800C63EFF /* Hash.c in Sources */,
   8.660 +				646C410E1D510CD800C63EFF /* DeviceGroup-Protocol.c in Sources */,
   8.661  				64A826861B455D0800EECAF0 /* stringlist.c in Sources */,
   8.662 +				4354FF651D6EDF300033069C /* sync_impl.c in Sources */,
   8.663  				64A8267E1B455D0800EECAF0 /* message_api.c in Sources */,
   8.664 -				6406CED71CE3835300C14D77 /* constr_SEQUENCE_OF.c in Sources */,
   8.665  				64A826851B455D0800EECAF0 /* sqlite3.c in Sources */,
   8.666 +				646C41361D510CD800C63EFF /* Version.c in Sources */,
   8.667 +				646C41081D510CD800C63EFF /* constr_TYPE.c in Sources */,
   8.668 +				646C40FE1D510CD800C63EFF /* BOOLEAN.c in Sources */,
   8.669 +				646C41001D510CD800C63EFF /* constr_CHOICE.c in Sources */,
   8.670 +				646C41121D510CD800C63EFF /* HandshakeRequest.c in Sources */,
   8.671 +				646C41471D510D2C00C63EFF /* sync_fsm.c in Sources */,
   8.672  				64A826821B455D0800EECAF0 /* pgp_netpgp.c in Sources */,
   8.673 -				6406CED31CE3835300C14D77 /* ber_tlv_tag.c in Sources */,
   8.674 -				6406CF011CE3835300C14D77 /* xer_support.c in Sources */,
   8.675 +				646C41101D510CD800C63EFF /* GroupKeys.c in Sources */,
   8.676 +				646C40EF1D510CD800C63EFF /* asn_SEQUENCE_OF.c in Sources */,
   8.677  				64A826891B455D0800EECAF0 /* trans_auto.c in Sources */,
   8.678 +				646C410C1D510CD800C63EFF /* der_encoder.c in Sources */,
   8.679 +				646C41381D510CD800C63EFF /* xer_decoder.c in Sources */,
   8.680 +				646C41181D510CD800C63EFF /* Hex.c in Sources */,
   8.681  				64A8267D1B455D0800EECAF0 /* keymanagement.c in Sources */,
   8.682 +				646C40EB1D510CD800C63EFF /* asn_codecs_prim.c in Sources */,
   8.683 +				646C41451D510D2C00C63EFF /* sync_actions.c in Sources */,
   8.684 +				646C40F61D510CD800C63EFF /* ber_decoder.c in Sources */,
   8.685 +				646C40F11D510CD800C63EFF /* asn_SET_OF.c in Sources */,
   8.686 +				4354FF691D6EE1A70033069C /* NULL.c in Sources */,
   8.687 +				646C413A1D510CD800C63EFF /* xer_encoder.c in Sources */,
   8.688 +				646C41021D510CD800C63EFF /* constr_SEQUENCE_OF.c in Sources */,
   8.689 +				646C410A1D510CD800C63EFF /* constraints.c in Sources */,
   8.690 +				646C41461D510D2C00C63EFF /* sync_driver.c in Sources */,
   8.691  				64A8267C1B455D0800EECAF0 /* identity_list.c in Sources */,
   8.692 -				64D2C84A1CE2245D002CD757 /* sync.c in Sources */,
   8.693 -				6406CED11CE3835300C14D77 /* ber_tlv_length.c in Sources */,
   8.694 -				6406CECA1CE3835300C14D77 /* asn_SEQUENCE_OF.c in Sources */,
   8.695 -				6406CECC1CE3835300C14D77 /* asn_SET_OF.c in Sources */,
   8.696 -				6406CED51CE3835300C14D77 /* BIT_STRING.c in Sources */,
   8.697 +				646C40FC1D510CD800C63EFF /* BIT_STRING.c in Sources */,
   8.698 +				646C40F41D510CD800C63EFF /* Beacon.c in Sources */,
   8.699 +				646C411E1D510CD800C63EFF /* INTEGER.c in Sources */,
   8.700 +				646C413C1D510CD800C63EFF /* xer_support.c in Sources */,
   8.701  				64A8268A1B455D0800EECAF0 /* transport.c in Sources */,
   8.702 -				6406CEE11CE3835300C14D77 /* der_encoder.c in Sources */,
   8.703 -				6406CEF51CE3835300C14D77 /* PrintableString.c in Sources */,
   8.704 -				6406CED91CE3835300C14D77 /* constr_SEQUENCE.c in Sources */,
   8.705 -				6406CEEF1CE3835300C14D77 /* per_encoder.c in Sources */,
   8.706 +				646C41491D510D2C00C63EFF /* sync_send_actions.c in Sources */,
   8.707 +				646C41201D510CD800C63EFF /* ISO639-1.c in Sources */,
   8.708 +				646C414A1D510D2C00C63EFF /* sync.c in Sources */,
   8.709  				64A826791B455D0800EECAF0 /* cryptotech.c in Sources */,
   8.710 +				43BA0F461D7964750059172F /* asn1_helper.c in Sources */,
   8.711 +				646C412A1D510CD800C63EFF /* per_encoder.c in Sources */,
   8.712 +				646C412E1D510CD800C63EFF /* per_support.c in Sources */,
   8.713  				64A826781B455D0800EECAF0 /* bloblist.c in Sources */,
   8.714 -				6406CEEB1CE3835300C14D77 /* OCTET_STRING.c in Sources */,
   8.715 -				6406CEF31CE3835300C14D77 /* per_support.c in Sources */,
   8.716 -				6406CEE71CE3835300C14D77 /* NativeEnumerated.c in Sources */,
   8.717 -				6406CEDD1CE3835300C14D77 /* constr_TYPE.c in Sources */,
   8.718 +				646C41041D510CD800C63EFF /* constr_SEQUENCE.c in Sources */,
   8.719  				64A826881B455D0800EECAF0 /* timestamp.c in Sources */,
   8.720 -				6406CEFF1CE3835300C14D77 /* xer_encoder.c in Sources */,
   8.721 +				646C41221D510CD800C63EFF /* NativeEnumerated.c in Sources */,
   8.722  				430D258B1C9ED75A00B94535 /* blacklist.c in Sources */,
   8.723 +				646C414E1D510D8800C63EFF /* baseprotocol.c in Sources */,
   8.724  				6467888C1CEB3D120001F54C /* map_asn1.c in Sources */,
   8.725 -				6406CEF11CE3835300C14D77 /* per_opentype.c in Sources */,
   8.726 -				6467888E1CEB3D120001F54C /* sync_actions.c in Sources */,
   8.727 -				6406CEED1CE3835300C14D77 /* per_decoder.c in Sources */,
   8.728 +				646C40FA1D510CD800C63EFF /* ber_tlv_tag.c in Sources */,
   8.729 +				646C41241D510CD800C63EFF /* NativeInteger.c in Sources */,
   8.730 +				646C41061D510CD800C63EFF /* constr_SET_OF.c in Sources */,
   8.731 +				646C412C1D510CD800C63EFF /* per_opentype.c in Sources */,
   8.732 +				646C41281D510CD800C63EFF /* per_decoder.c in Sources */,
   8.733  				64A826801B455D0800EECAF0 /* mime.c in Sources */,
   8.734 -				6406CEC61CE3835300C14D77 /* asn_codecs_prim.c in Sources */,
   8.735  				64A8267F1B455D0800EECAF0 /* message.c in Sources */,
   8.736 +				646C411A1D510CD800C63EFF /* Identity.c in Sources */,
   8.737  				64A826811B455D0800EECAF0 /* pEpEngine.c in Sources */,
   8.738 -				6406CEDB1CE3835300C14D77 /* constr_SET_OF.c in Sources */,
   8.739 -				6406CEF91CE3835300C14D77 /* UTF8String.c in Sources */,
   8.740 +				646C41321D510CD800C63EFF /* Sync-Protocols.c in Sources */,
   8.741  			);
   8.742  			runOnlyForDeploymentPostprocessing = 0;
   8.743  		};
     9.1 --- a/db/Makefile	Mon Oct 03 14:34:58 2016 +0200
     9.2 +++ b/db/Makefile	Wed Oct 05 15:38:42 2016 +0200
     9.3 @@ -12,6 +12,7 @@
     9.4  .PHONY: clean install
     9.5  
     9.6  install: system.db
     9.7 +	mkdir -p `dirname $(SYSTEM_DB)`
     9.8  	cp system.db $(SYSTEM_DB)
     9.9  
    9.10  clean:
    10.1 --- a/pEpEngine.vcxproj	Mon Oct 03 14:34:58 2016 +0200
    10.2 +++ b/pEpEngine.vcxproj	Wed Oct 05 15:38:42 2016 +0200
    10.3 @@ -65,7 +65,7 @@
    10.4      <Link>
    10.5        <SubSystem>Windows</SubSystem>
    10.6        <GenerateDebugInformation>true</GenerateDebugInformation>
    10.7 -      <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;%(AdditionalDependencies)</AdditionalDependencies>
    10.8 +      <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
    10.9      </Link>
   10.10      <PreBuildEvent>
   10.11        <Command>
   10.12 @@ -84,13 +84,15 @@
   10.13        <TreatWarningAsError>false</TreatWarningAsError>
   10.14        <AdditionalIncludeDirectories>C:\Users\vb\share\asn1c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
   10.15        <CompileAs>Default</CompileAs>
   10.16 +      <MultiProcessorCompilation>true</MultiProcessorCompilation>
   10.17 +      <ControlFlowGuard>Guard</ControlFlowGuard>
   10.18      </ClCompile>
   10.19      <Link>
   10.20        <SubSystem>Windows</SubSystem>
   10.21        <GenerateDebugInformation>true</GenerateDebugInformation>
   10.22        <EnableCOMDATFolding>true</EnableCOMDATFolding>
   10.23        <OptimizeReferences>true</OptimizeReferences>
   10.24 -      <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.25 +      <AdditionalDependencies>$(TargetDir)\pEpEngineASN1.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies>
   10.26      </Link>
   10.27      <PreBuildEvent>
   10.28        <Command>
   10.29 @@ -98,6 +100,7 @@
   10.30      </PreBuildEvent>
   10.31    </ItemDefinitionGroup>
   10.32    <ItemGroup>
   10.33 +    <ClCompile Include="src\asn1_helper.c" />
   10.34      <ClCompile Include="src\baseprotocol.c" />
   10.35      <ClCompile Include="src\blacklist.c" />
   10.36      <ClCompile Include="src\bloblist.c" />
   10.37 @@ -121,12 +124,14 @@
   10.38      <ClCompile Include="src\sync_actions.c" />
   10.39      <ClCompile Include="src\sync_driver.c" />
   10.40      <ClCompile Include="src\sync_fsm.c" />
   10.41 +    <ClCompile Include="src\sync_impl.c" />
   10.42      <ClCompile Include="src\sync_send_actions.c" />
   10.43      <ClCompile Include="src\timestamp.c" />
   10.44      <ClCompile Include="src\transport.c" />
   10.45      <ClCompile Include="src\trans_auto.c" />
   10.46    </ItemGroup>
   10.47    <ItemGroup>
   10.48 +    <ClInclude Include="src\asn1_helper.h" />
   10.49      <ClInclude Include="src\baseprotocol.h" />
   10.50      <ClInclude Include="src\blacklist.h" />
   10.51      <ClInclude Include="src\bloblist.h" />
   10.52 @@ -153,6 +158,7 @@
   10.53      <ClInclude Include="src\stringpair.h" />
   10.54      <ClInclude Include="src\sync.h" />
   10.55      <ClInclude Include="src\sync_fsm.h" />
   10.56 +    <ClInclude Include="src\sync_impl.h" />
   10.57      <ClInclude Include="src\timestamp.h" />
   10.58      <ClInclude Include="src\transport.h" />
   10.59      <ClInclude Include="src\trans_auto.h" />
    11.1 --- a/pEpEngine.vcxproj.filters	Mon Oct 03 14:34:58 2016 +0200
    11.2 +++ b/pEpEngine.vcxproj.filters	Wed Oct 05 15:38:42 2016 +0200
    11.3 @@ -96,6 +96,12 @@
    11.4      <ClCompile Include="src\openpgp_compat.c">
    11.5        <Filter>Quelldateien</Filter>
    11.6      </ClCompile>
    11.7 +    <ClCompile Include="src\asn1_helper.c">
    11.8 +      <Filter>Quelldateien</Filter>
    11.9 +    </ClCompile>
   11.10 +    <ClCompile Include="src\sync_impl.c">
   11.11 +      <Filter>Quelldateien</Filter>
   11.12 +    </ClCompile>
   11.13    </ItemGroup>
   11.14    <ItemGroup>
   11.15      <ClInclude Include="src\keymanagement.h">
   11.16 @@ -188,6 +194,12 @@
   11.17      <ClInclude Include="src\openpgp_compat.h">
   11.18        <Filter>Headerdateien</Filter>
   11.19      </ClInclude>
   11.20 +    <ClInclude Include="src\asn1_helper.h">
   11.21 +      <Filter>Headerdateien</Filter>
   11.22 +    </ClInclude>
   11.23 +    <ClInclude Include="src\sync_impl.h">
   11.24 +      <Filter>Headerdateien</Filter>
   11.25 +    </ClInclude>
   11.26    </ItemGroup>
   11.27    <ItemGroup>
   11.28      <Text Include="LICENSE.txt" />
    12.1 --- a/src/Makefile	Mon Oct 03 14:34:58 2016 +0200
    12.2 +++ b/src/Makefile	Wed Oct 05 15:38:42 2016 +0200
    12.3 @@ -5,14 +5,14 @@
    12.4  ifeq ($(BUILD_ON),Darwin)
    12.5  ifeq ($(BUILD_FOR),Darwin)
    12.6  
    12.7 -TARGET=libpEpEngine.dylib
    12.8 +TARGET?=libpEpEngine.dylib
    12.9  MACOSX_VERSION_MIN=10.6
   12.10  GPGME_IN=$(HOME)
   12.11  LIBGPGME=libgpgme-pthread.dylib
   12.12  CC?=clang -std=c99 -pthread
   12.13  LD?=clang
   12.14  CFLAGS?=-I$(GPGME_IN)/include -I$(HOME)/include -I/opt/local/include $(OPTIMIZE) -pedantic \
   12.15 -	-DSYSTEM_DB=\"$(SYSTEM_DB)\" -DLIBGPGME=\"$(LIBGPGME)\" -I../asn.1
   12.16 +	-DSYSTEM_DB=\"$(SYSTEM_DB)\" -DLIBGPGME=\"$(LIBGPGME)\" -I../asn.1 $(EXTRAMACROS)
   12.17  LDFLAGS?=-lc -shared -arch x86_64 \
   12.18  	-L$(HOME)/lib -L/usr/lib -L/opt/local/lib -letpan -lsqlite3 -L../asn.1 -lasn1 -lz -liconv
   12.19  
   12.20 @@ -29,7 +29,7 @@
   12.21  CC=gcc -std=c99
   12.22  CFLAGS?=-I$(GPGME_IN)/include $(OPTIMIZE) -fPIC -pedantic \
   12.23  	-DSYSTEM_DB=\"$(SYSTEM_DB)\" -DLIBGPGME=\"$(LIBGPGME)\" \
   12.24 -	-DSQLITE_THREADSAFE=1 -D_GNU_SOURCE -I../asn.1
   12.25 +	-DSQLITE_THREADSAFE=1 -D_GNU_SOURCE -I../asn.1 $(EXTRAMACROS)
   12.26  LDFLAGS?=-L$(GPGME_IN)/lib -shared -lc -ldl -letpan -lpthread -L../asn.1 -lasn1
   12.27  
   12.28  else
   12.29 @@ -88,7 +88,7 @@
   12.30  install: $(TARGET)
   12.31  	cp $< $(PREFIX)/lib/
   12.32  	mkdir -p $(PREFIX)/include/pEp
   12.33 -	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h $(PREFIX)/include/pEp/
   12.34 +	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h sync_fsm.h $(PREFIX)/include/pEp/
   12.35  
   12.36  uninstall:
   12.37  	rm -f $(PREFIX)/lib/$(TARGET)
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/asn1_helper.c	Wed Oct 05 15:38:42 2016 +0200
    13.3 @@ -0,0 +1,37 @@
    13.4 +#include "asn1_helper.h"
    13.5 +#include <assert.h>
    13.6 +#include <stdlib.h>
    13.7 +
    13.8 +growing_buf_t *new_growing_buf(void)
    13.9 +{
   13.10 +    growing_buf_t *result = calloc(1, sizeof(growing_buf_t));
   13.11 +    assert(result);
   13.12 +    return result;
   13.13 +}
   13.14 +
   13.15 +void free_growing_buf(growing_buf_t *buf)
   13.16 +{
   13.17 +    if (buf) {
   13.18 +        free(buf->data);
   13.19 +        free(buf);
   13.20 +    }
   13.21 +}
   13.22 +
   13.23 +int consume_bytes(const void *src, size_t size, growing_buf_t *dst)
   13.24 +{
   13.25 +    assert(src && dst);
   13.26 +    if (!(src && dst))
   13.27 +        return -1;
   13.28 +
   13.29 +    char *new_data = realloc(dst->data, dst->size + size + 1);
   13.30 +    assert(new_data);
   13.31 +    if (!new_data)
   13.32 +        return -1;
   13.33 +    dst->data = new_data;
   13.34 +    memcpy(dst->data + dst->size, src, size);
   13.35 +    dst->size += size;
   13.36 +    dst->data[dst->size] = 0; // safeguard
   13.37 +
   13.38 +    return 1;
   13.39 +}
   13.40 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/asn1_helper.h	Wed Oct 05 15:38:42 2016 +0200
    14.3 @@ -0,0 +1,13 @@
    14.4 +#pragma once
    14.5 +
    14.6 +#include <string.h>
    14.7 +
    14.8 +typedef struct growing_buf {
    14.9 +    char *data;
   14.10 +    size_t size;
   14.11 +} growing_buf_t;
   14.12 +
   14.13 +growing_buf_t *new_growing_buf(void);
   14.14 +void free_growing_buf(growing_buf_t *buf);
   14.15 +int consume_bytes(const void *src, size_t size, growing_buf_t *dst);
   14.16 +
    15.1 --- a/src/baseprotocol.c	Mon Oct 03 14:34:58 2016 +0200
    15.2 +++ b/src/baseprotocol.c	Wed Oct 05 15:38:42 2016 +0200
    15.3 @@ -1,4 +1,5 @@
    15.4  #include "pEp_internal.h"
    15.5 +#include "message_api.h"
    15.6  
    15.7  PEP_STATUS decorate_message(
    15.8          message *msg,
    15.9 @@ -14,7 +15,7 @@
   15.10          return PEP_ILLEGAL_VALUE;
   15.11  
   15.12      bloblist_t *bl = bloblist_add(msg->attachments, payload, size,
   15.13 -            "application/pEp", "auto.pEp");
   15.14 +            "application/pEp.sync", "ignore_this_attachment.pEp");
   15.15      if (bl == NULL)
   15.16          goto enomem;
   15.17  
   15.18 @@ -50,6 +51,8 @@
   15.19      if (!msg)
   15.20          goto enomem;
   15.21  
   15.22 +    add_opt_field(msg, "pEp-auto-consume", "yes");
   15.23 +
   15.24      msg->from = identity_dup(me);
   15.25      if (!msg->from)
   15.26          goto enomem;
   15.27 @@ -58,7 +61,7 @@
   15.28      if (!msg->to)
   15.29          goto enomem;
   15.30  
   15.31 -    msg->shortmsg = strdup("pEp");
   15.32 +    msg->shortmsg = strdup("p≡p synchronization message - please ignore");
   15.33      assert(msg->shortmsg);
   15.34      if (!msg->shortmsg)
   15.35          goto enomem;
    16.1 --- a/src/bloblist.c	Mon Oct 03 14:34:58 2016 +0200
    16.2 +++ b/src/bloblist.c	Wed Oct 05 15:38:42 2016 +0200
    16.3 @@ -165,3 +165,4 @@
    16.4  
    16.5      return len;
    16.6  }
    16.7 +
    17.1 --- a/src/cryptotech.c	Mon Oct 03 14:34:58 2016 +0200
    17.2 +++ b/src/cryptotech.c	Wed Oct 05 15:38:42 2016 +0200
    17.3 @@ -46,6 +46,7 @@
    17.4          cryptotech[PEP_crypt_OpenPGP].revoke_key = pgp_revoke_key;
    17.5          cryptotech[PEP_crypt_OpenPGP].key_expired = pgp_key_expired;
    17.6          cryptotech[PEP_crypt_OpenPGP].key_revoked = pgp_key_revoked;
    17.7 +        cryptotech[PEP_crypt_OpenPGP].key_created = pgp_key_created;
    17.8  #ifdef PGP_BINARY_PATH
    17.9          cryptotech[PEP_crypt_OpenPGP].binary_path = PGP_BINARY_PATH;
   17.10  #endif
    18.1 --- a/src/cryptotech.h	Mon Oct 03 14:34:58 2016 +0200
    18.2 +++ b/src/cryptotech.h	Wed Oct 05 15:38:42 2016 +0200
    18.3 @@ -30,7 +30,8 @@
    18.4  typedef PEP_STATUS (*delete_keypair_t)(PEP_SESSION session, const char *fpr);
    18.5  
    18.6  typedef PEP_STATUS (*export_key_t)(
    18.7 -        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
    18.8 +        PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
    18.9 +        bool secret
   18.10      );
   18.11  
   18.12  typedef PEP_STATUS (*find_keys_t)(
   18.13 @@ -64,7 +65,10 @@
   18.14          const time_t when, bool *expired);
   18.15  
   18.16  typedef PEP_STATUS (*key_revoked_t)(PEP_SESSION session, const char *fpr,
   18.17 -                                    bool *revoked);
   18.18 +        bool *revoked);
   18.19 +
   18.20 +typedef PEP_STATUS (*key_created_t)(PEP_SESSION session, const char *fpr,
   18.21 +        time_t *created);
   18.22  
   18.23  typedef PEP_STATUS (*binary_path_t)(const char **path);
   18.24  
   18.25 @@ -88,6 +92,7 @@
   18.26      revoke_key_t revoke_key;
   18.27      key_expired_t key_expired;
   18.28      key_revoked_t key_revoked;
   18.29 +    key_created_t key_created;
   18.30      binary_path_t binary_path;
   18.31  } PEP_cryptotech_t;
   18.32  
    19.1 --- a/src/keymanagement.c	Mon Oct 03 14:34:58 2016 +0200
    19.2 +++ b/src/keymanagement.c	Wed Oct 05 15:38:42 2016 +0200
    19.3 @@ -9,6 +9,8 @@
    19.4  #include "pEp_internal.h"
    19.5  #include "keymanagement.h"
    19.6  
    19.7 +#include "sync_fsm.h"
    19.8 +
    19.9  #ifndef EMPTYSTR
   19.10  #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
   19.11  #endif
   19.12 @@ -121,11 +123,23 @@
   19.13      if (!(session && identity && !EMPTYSTR(identity->address)))
   19.14          return PEP_ILLEGAL_VALUE;
   19.15  
   19.16 +    if (identity->me || (identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0)) {
   19.17 +        identity->me = true;
   19.18 +        return myself(session, identity);
   19.19 +    }
   19.20 +
   19.21      int _no_user_id = EMPTYSTR(identity->user_id);
   19.22      int _did_elect_new_key = 0;
   19.23  
   19.24      if (_no_user_id)
   19.25      {
   19.26 +        status = get_identity(session, identity->address, PEP_OWN_USERID,
   19.27 +                &stored_identity);
   19.28 +        if (status == PEP_STATUS_OK) {
   19.29 +            free_identity(stored_identity);
   19.30 +            return myself(session, identity);
   19.31 +        }
   19.32 +
   19.33          free(identity->user_id);
   19.34  
   19.35          identity->user_id = calloc(1, strlen(identity->address) + 6);
   19.36 @@ -405,32 +419,30 @@
   19.37  
   19.38      assert(session);
   19.39      assert(identity);
   19.40 -    assert(identity->address);
   19.41 -    assert(identity->username);
   19.42 +    assert(!EMPTYSTR(identity->address));
   19.43 +
   19.44      assert(EMPTYSTR(identity->user_id) ||
   19.45             strcmp(identity->user_id, PEP_OWN_USERID) == 0);
   19.46  
   19.47 -    if (!(session && identity && identity->address && identity->username &&
   19.48 -          (EMPTYSTR(identity->user_id) ||
   19.49 -           strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
   19.50 +    if (!(session && identity && !EMPTYSTR(identity->address) &&
   19.51 +            (EMPTYSTR(identity->user_id) ||
   19.52 +            strcmp(identity->user_id, PEP_OWN_USERID) == 0)))
   19.53          return PEP_ILLEGAL_VALUE;
   19.54  
   19.55      identity->comm_type = PEP_ct_pEp;
   19.56      identity->me = true;
   19.57      
   19.58 -    if(EMPTYSTR(identity->user_id))
   19.59 +    if (EMPTYSTR(identity->user_id))
   19.60      {
   19.61          free(identity->user_id);
   19.62          identity->user_id = strdup(PEP_OWN_USERID);
   19.63          assert(identity->user_id);
   19.64          if (identity->user_id == NULL)
   19.65 -        {
   19.66              return PEP_OUT_OF_MEMORY;
   19.67 -        }
   19.68      }
   19.69  
   19.70      DEBUG_LOG("myself", "debug", identity->address);
   19.71 -    
   19.72 + 
   19.73      status = get_identity(session,
   19.74                            identity->address,
   19.75                            identity->user_id,
   19.76 @@ -493,7 +505,9 @@
   19.77              return status;
   19.78          }
   19.79      }
   19.80 -    
   19.81 +   
   19.82 +    bool new_key_generated = false;
   19.83 +
   19.84      if (EMPTYSTR(identity->fpr) || revoked)
   19.85      {        
   19.86          if(revoked)
   19.87 @@ -513,6 +527,8 @@
   19.88                  free(r_fpr);
   19.89              return status;
   19.90          }
   19.91 +
   19.92 +        new_key_generated = true;
   19.93          
   19.94          if(revoked)
   19.95          {
   19.96 @@ -549,6 +565,14 @@
   19.97          return status;
   19.98      }
   19.99  
  19.100 +    if(new_key_generated)
  19.101 +    {
  19.102 +        // if a state machine for keysync is in place, inject notify
  19.103 +        status = inject_DeviceState_event(session, KeyGen, NULL, NULL);
  19.104 +        if (status != PEP_STATUS_OK)
  19.105 +            return status;
  19.106 +    }
  19.107 +
  19.108      return PEP_STATUS_OK;
  19.109  
  19.110  }
  19.111 @@ -617,7 +641,7 @@
  19.112      return PEP_STATUS_OK;
  19.113  }
  19.114  
  19.115 -DYNAMIC_API PEP_STATUS key_compromized(
  19.116 +DYNAMIC_API PEP_STATUS key_mistrusted(
  19.117          PEP_SESSION session,
  19.118          pEp_identity *ident
  19.119      )
  19.120 @@ -715,10 +739,10 @@
  19.121  }
  19.122  
  19.123  DYNAMIC_API PEP_STATUS own_key_is_listed(
  19.124 -                                           PEP_SESSION session,
  19.125 -                                           const char *fpr,
  19.126 -                                           bool *listed
  19.127 -                                           )
  19.128 +        PEP_SESSION session,
  19.129 +        const char *fpr,
  19.130 +        bool *listed
  19.131 +    )
  19.132  {
  19.133      PEP_STATUS status = PEP_STATUS_OK;
  19.134      int count;
  19.135 @@ -751,39 +775,69 @@
  19.136      return status;
  19.137  }
  19.138  
  19.139 -DYNAMIC_API PEP_STATUS own_key_retrieve(
  19.140 -                                          PEP_SESSION session,
  19.141 -                                          stringlist_t **own_key
  19.142 -                                          )
  19.143 +DYNAMIC_API PEP_STATUS own_identities_retrieve(
  19.144 +        PEP_SESSION session,
  19.145 +        identity_list **own_identities
  19.146 +      )
  19.147  {
  19.148      PEP_STATUS status = PEP_STATUS_OK;
  19.149      
  19.150 -    assert(session);
  19.151 -    assert(own_key);
  19.152 -    
  19.153 -    if (!(session && own_key))
  19.154 +    assert(session && own_identities);
  19.155 +    if (!(session && own_identities))
  19.156          return PEP_ILLEGAL_VALUE;
  19.157      
  19.158 -    *own_key = NULL;
  19.159 -    stringlist_t *_own_key = new_stringlist(NULL);
  19.160 -    if (_own_key == NULL)
  19.161 +    *own_identities = NULL;
  19.162 +    identity_list *_own_identities = new_identity_list(NULL);
  19.163 +    if (_own_identities == NULL)
  19.164          goto enomem;
  19.165      
  19.166 -    sqlite3_reset(session->own_key_retrieve);
  19.167 +    sqlite3_reset(session->own_identities_retrieve);
  19.168      
  19.169      int result;
  19.170 +    // address, fpr, username, user_id, comm_type, lang, flags
  19.171 +    const char *address = NULL;
  19.172      const char *fpr = NULL;
  19.173 +    const char *username = NULL;
  19.174 +    const char *user_id = NULL;
  19.175 +    PEP_comm_type comm_type = PEP_ct_unknown;
  19.176 +    const char *lang = NULL;
  19.177 +    unsigned int flags = 0;
  19.178      
  19.179 -    stringlist_t *_bl = _own_key;
  19.180 +    identity_list *_bl = _own_identities;
  19.181      do {
  19.182 -        result = sqlite3_step(session->own_key_retrieve);
  19.183 +        result = sqlite3_step(session->own_identities_retrieve);
  19.184          switch (result) {
  19.185              case SQLITE_ROW:
  19.186 -                fpr = (const char *) sqlite3_column_text(session->own_key_retrieve, 0);
  19.187 -                
  19.188 -                _bl = stringlist_add(_bl, fpr);
  19.189 -                if (_bl == NULL)
  19.190 +                address = (const char *)
  19.191 +                    sqlite3_column_text(session->own_identities_retrieve, 0);
  19.192 +                fpr = (const char *)
  19.193 +                    sqlite3_column_text(session->own_identities_retrieve, 1);
  19.194 +                user_id = PEP_OWN_USERID;
  19.195 +                username = (const char *)
  19.196 +                    sqlite3_column_text(session->own_identities_retrieve, 2);
  19.197 +                comm_type = PEP_ct_pEp;
  19.198 +                lang = (const char *)
  19.199 +                    sqlite3_column_text(session->own_identities_retrieve, 3);
  19.200 +                flags = (unsigned int)
  19.201 +                    sqlite3_column_int(session->own_key_is_listed, 4);
  19.202 +
  19.203 +                pEp_identity *ident = new_identity(address, fpr, user_id, username);
  19.204 +                if (!ident)
  19.205                      goto enomem;
  19.206 +                ident->comm_type = comm_type;
  19.207 +                if (lang && lang[0]) {
  19.208 +                    ident->lang[0] = lang[0];
  19.209 +                    ident->lang[1] = lang[1];
  19.210 +                    ident->lang[2] = 0;
  19.211 +                }
  19.212 +                ident->me = true;
  19.213 +                ident->flags = flags;
  19.214 +
  19.215 +                _bl = identity_list_add(_bl, ident);
  19.216 +                if (_bl == NULL) {
  19.217 +                    free_identity(ident);
  19.218 +                    goto enomem;
  19.219 +                }
  19.220                  
  19.221                  break;
  19.222                  
  19.223 @@ -796,18 +850,19 @@
  19.224          }
  19.225      } while (result != SQLITE_DONE);
  19.226      
  19.227 -    sqlite3_reset(session->own_key_retrieve);
  19.228 +    sqlite3_reset(session->own_identities_retrieve);
  19.229      if (status == PEP_STATUS_OK)
  19.230 -        *own_key = _own_key;
  19.231 +        *own_identities = _own_identities;
  19.232      else
  19.233 -        free_stringlist(_own_key);
  19.234 +        free_identity_list(_own_identities);
  19.235      
  19.236      goto the_end;
  19.237      
  19.238  enomem:
  19.239 -    free_stringlist(_own_key);
  19.240 +    free_identity_list(_own_identities);
  19.241      status = PEP_OUT_OF_MEMORY;
  19.242      
  19.243  the_end:
  19.244      return status;
  19.245  }
  19.246 +
    20.1 --- a/src/keymanagement.h	Mon Oct 03 14:34:58 2016 +0200
    20.2 +++ b/src/keymanagement.h	Wed Oct 05 15:38:42 2016 +0200
    20.3 @@ -117,13 +117,13 @@
    20.4      );
    20.5  
    20.6  
    20.7 -// key_compromized() - mark key as being compromized
    20.8 +// key_mistrusted() - mark key as being compromized
    20.9  //
   20.10  //  parameters:
   20.11  //      session (in)        session to use
   20.12  //      ident (in)          person and key which was compromized
   20.13  
   20.14 -DYNAMIC_API PEP_STATUS key_compromized(
   20.15 +DYNAMIC_API PEP_STATUS key_mistrusted(
   20.16          PEP_SESSION session,
   20.17          pEp_identity *ident
   20.18      );
   20.19 @@ -144,7 +144,7 @@
   20.20      );
   20.21  
   20.22  
   20.23 -// key_reset_trust() - undo trust_personal_key and key_compromized() for keys
   20.24 +// key_reset_trust() - undo trust_personal_key and key_mistrusted() for keys
   20.25  //                     we don't own
   20.26  //
   20.27  //  parameters:
   20.28 @@ -171,18 +171,18 @@
   20.29      );
   20.30  
   20.31  
   20.32 -// own_key_retrieve() - retrieve all own keys fingerprints
   20.33 +// own_identities_retrieve() - retrieve all own identities
   20.34  //
   20.35  //  parameters:
   20.36 -//      session (in)        session to use
   20.37 -//      own_key (out)     copy of own_key
   20.38 +//      session (in)            session to use
   20.39 +//      own_identities (out)    list of own identities
   20.40  //
   20.41  //  caveat:
   20.42 -//      the ownership of the copy of own_key goes to the caller
   20.43 +//      the ownership of the copy of own_identities goes to the caller
   20.44  
   20.45 -DYNAMIC_API PEP_STATUS own_key_retrieve(
   20.46 +DYNAMIC_API PEP_STATUS own_identities_retrieve(
   20.47          PEP_SESSION session,
   20.48 -        stringlist_t **own_key
   20.49 +        identity_list **own_identities
   20.50      );
   20.51  
   20.52  #ifdef __cplusplus
    21.1 --- a/src/map_asn1.c	Mon Oct 03 14:34:58 2016 +0200
    21.2 +++ b/src/map_asn1.c	Wed Oct 05 15:38:42 2016 +0200
    21.3 @@ -51,10 +51,12 @@
    21.4      }
    21.5  
    21.6      if (ident->lang[0]) {
    21.7 -        result->lang = OCTET_STRING_new_fromBuf(&asn_DEF_ISO639_1,
    21.8 -                ident->lang, 2);
    21.9 -        if (!result->lang)
   21.10 -            goto enomem;
   21.11 +        int r = OCTET_STRING_fromBuf(&result->lang, ident->lang, 2);
   21.12 +        assert(r == 0);
   21.13 +    }
   21.14 +    else {
   21.15 +        int r = OCTET_STRING_fromBuf(&result->lang, "en", 2);
   21.16 +        assert(r == 0);
   21.17      }
   21.18  
   21.19      return result;
   21.20 @@ -107,9 +109,10 @@
   21.21      if (ident->comm_type)
   21.22          result->comm_type = (PEP_comm_type) *ident->comm_type;
   21.23  
   21.24 -    if (ident->lang) {
   21.25 -        result->lang[0] = ident->lang->buf[0];
   21.26 -        result->lang[1] = ident->lang->buf[1];
   21.27 +    if (ident->lang.size == 2) {
   21.28 +        result->lang[0] = ident->lang.buf[0];
   21.29 +        result->lang[1] = ident->lang.buf[1];
   21.30 +        result->lang[2] = 0;
   21.31      }
   21.32  
   21.33      return result;
   21.34 @@ -119,9 +122,9 @@
   21.35      return NULL;
   21.36  }
   21.37  
   21.38 -KeyList_t *KeyList_from_stringlist(
   21.39 -        const stringlist_t *list,
   21.40 -        KeyList_t *result
   21.41 +IdentityList_t *IdentityList_from_identity_list(
   21.42 +        const identity_list *list,
   21.43 +        IdentityList_t *result
   21.44      )
   21.45  {
   21.46      assert(list);
   21.47 @@ -129,18 +132,15 @@
   21.48          return NULL;
   21.49  
   21.50      if (!result)
   21.51 -        result = (KeyList_t *) calloc(1, sizeof(KeyList_t));
   21.52 +        result = (IdentityList_t *) calloc(1, sizeof(IdentityList_t));
   21.53      assert(result);
   21.54      if (!result)
   21.55          return NULL;
   21.56  
   21.57 -    for (const stringlist_t *l = list; l && l->value; l=l->next) {
   21.58 -        Hash_t *key = OCTET_STRING_new_fromBuf(&asn_DEF_Hash, l->value, -1);
   21.59 -        if (!key)
   21.60 -            goto enomem;
   21.61 -
   21.62 -        if (ASN_SEQUENCE_ADD(&result->list, key)) {
   21.63 -            ASN_STRUCT_FREE(asn_DEF_Hash, key);
   21.64 +    for (const identity_list *l = list; l && l->ident; l=l->next) {
   21.65 +        Identity_t *ident = Identity_from_Struct(l->ident, NULL);
   21.66 +        if (ASN_SEQUENCE_ADD(&result->list, ident)) {
   21.67 +            ASN_STRUCT_FREE(asn_DEF_Identity, ident);
   21.68              goto enomem;
   21.69          }
   21.70      }
   21.71 @@ -148,30 +148,25 @@
   21.72      return result;
   21.73  
   21.74  enomem:
   21.75 -    ASN_STRUCT_FREE(asn_DEF_KeyList, result);
   21.76 +    ASN_STRUCT_FREE(asn_DEF_IdentityList, result);
   21.77      return NULL;
   21.78  }
   21.79  
   21.80 -stringlist_t *KeyList_to_stringlist(KeyList_t *list, stringlist_t *result)
   21.81 +identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list *result)
   21.82  {
   21.83      assert(list);
   21.84      if (!list)
   21.85          return NULL;
   21.86  
   21.87      if (!result)
   21.88 -        result = new_stringlist(NULL);
   21.89 +        result = new_identity_list(NULL);
   21.90      if (!result)
   21.91          return NULL;
   21.92  
   21.93 -    stringlist_t *r = result;
   21.94 +    identity_list *r = result;
   21.95      for (int i=0; i<list->list.count; i++) {
   21.96 -        char *str = strndup((char *) list->list.array[i]->buf,
   21.97 -                list->list.array[i]->size);
   21.98 -        assert(str);
   21.99 -        if (!str)
  21.100 -            goto enomem;
  21.101 -        r = stringlist_add(r, str);
  21.102 -        free(str);
  21.103 +        pEp_identity *ident = Identity_to_Struct(list->list.array[i], NULL);
  21.104 +        r = identity_list_add(r, ident);
  21.105          if (!r)
  21.106              goto enomem;
  21.107      }
  21.108 @@ -179,7 +174,7 @@
  21.109      return result;
  21.110  
  21.111  enomem:
  21.112 -    free_stringlist(result);
  21.113 +    free_identity_list(result);
  21.114      return NULL;
  21.115  }
  21.116  
    22.1 --- a/src/map_asn1.h	Mon Oct 03 14:34:58 2016 +0200
    22.2 +++ b/src/map_asn1.h	Wed Oct 05 15:38:42 2016 +0200
    22.3 @@ -1,9 +1,9 @@
    22.4  #pragma once
    22.5  
    22.6  #include "pEpEngine.h"
    22.7 -#include "stringlist.h"
    22.8 +#include "identity_list.h"
    22.9  #include "../asn.1/Identity.h"
   22.10 -#include "../asn.1/KeyList.h"
   22.11 +#include "../asn.1/IdentityList.h"
   22.12  
   22.13  #ifdef __cplusplus
   22.14  extern "C" {
   22.15 @@ -43,11 +43,11 @@
   22.16  pEp_identity *Identity_to_Struct(Identity_t *ident, pEp_identity *result);
   22.17  
   22.18  
   22.19 -// KeyList_from_stringlist() - convert stringlist_t into ASN.1 KeyList_t
   22.20 +// IdentityList_from_identity_list() - convert identity_list_t into ASN.1 IdentityList_t
   22.21  //
   22.22  //  params:
   22.23 -//      list (in)           stringlist_t to convert
   22.24 -//      result (inout)      KeyList_t to update or NULL to alloc a new one
   22.25 +//      list (in)           identity_list to convert
   22.26 +//      result (inout)      IdentityList_t to update or NULL to alloc a new one
   22.27  //
   22.28  //  return value:
   22.29  //      pointer to updated or allocated result
   22.30 @@ -55,16 +55,16 @@
   22.31  //  caveat:
   22.32  //      if a new struct is allocated, the ownership goes to the caller
   22.33  
   22.34 -KeyList_t *KeyList_from_stringlist(
   22.35 -        const stringlist_t *list,
   22.36 -        KeyList_t *result
   22.37 +IdentityList_t *IdentityList_from_identity_list(
   22.38 +        const identity_list *list,
   22.39 +        IdentityList_t *result
   22.40      );
   22.41  
   22.42 -// KeyList_to_stringlist() - convert ASN.1 KeyList_t to stringlist_t
   22.43 +// IdentityList_to_identity_list() - convert ASN.1 IdentityList_t to identity_list_t
   22.44  //
   22.45  //  params:
   22.46 -//      list (in)           ASN.1 KeyList_t to convert
   22.47 -//      result (inout)      stringlist_t to update or NULL to alloc a new one
   22.48 +//      list (in)           ASN.1 IdentityList_t to convert
   22.49 +//      result (inout)      identity_list_t to update or NULL to alloc a new one
   22.50  //
   22.51  //  return value:
   22.52  //      pointer to updated or allocated result
   22.53 @@ -72,7 +72,7 @@
   22.54  //  caveat:
   22.55  //      if a new struct is allocated, the ownership goes to the caller
   22.56  
   22.57 -stringlist_t *KeyList_to_stringlist(KeyList_t *list, stringlist_t *result);
   22.58 +identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list *result);
   22.59  
   22.60  
   22.61  #ifdef __cplusplus
    23.1 --- a/src/message_api.c	Mon Oct 03 14:34:58 2016 +0200
    23.2 +++ b/src/message_api.c	Wed Oct 05 15:38:42 2016 +0200
    23.3 @@ -3,17 +3,18 @@
    23.4  
    23.5  #include "platform.h"
    23.6  #include "mime.h"
    23.7 +#include "sync_fsm.h"
    23.8  
    23.9  #include <assert.h>
   23.10  #include <string.h>
   23.11  #include <stdlib.h>
   23.12  
   23.13  
   23.14 -#ifndef MIN
   23.15 -#define MIN(A, B) ((B) > (A) ? (A) : (B))
   23.16 +#ifndef _MIN
   23.17 +#define _MIN(A, B) ((B) > (A) ? (A) : (B))
   23.18  #endif
   23.19 -#ifndef MAX
   23.20 -#define MAX(A, B) ((B) > (A) ? (B) : (A))
   23.21 +#ifndef _MAX
   23.22 +#define _MAX(A, B) ((B) > (A) ? (B) : (A))
   23.23  #endif
   23.24  
   23.25  
   23.26 @@ -60,9 +61,9 @@
   23.27      return strcmp(bl->filename + (fn_len - fe_len), fe) == 0;
   23.28  }
   23.29  
   23.30 -static void add_opt_field(message *msg, const char *name, const char *value)
   23.31 +void add_opt_field(message *msg, const char *name, const char *value)
   23.32  {
   23.33 -    assert(msg);
   23.34 +    assert(msg && name && value);
   23.35  
   23.36      if (msg && name && value) {
   23.37          stringpair_t *pair = new_stringpair(name, value);
   23.38 @@ -296,6 +297,14 @@
   23.39              return PEP_OUT_OF_MEMORY;
   23.40      }
   23.41  
   23.42 +    free_stringpair_list(dst->opt_fields);
   23.43 +    dst->opt_fields = NULL;
   23.44 +    if (src->opt_fields) {
   23.45 +        dst->opt_fields = stringpair_list_dup(src->opt_fields);
   23.46 +        if (dst->opt_fields == NULL)
   23.47 +            return PEP_OUT_OF_MEMORY;
   23.48 +    }
   23.49 +
   23.50      return PEP_STATUS_OK;
   23.51  }
   23.52  
   23.53 @@ -602,9 +611,9 @@
   23.54      }
   23.55  }
   23.56  
   23.57 -static const char * color_to_string(PEP_color color)
   23.58 +static const char * rating_to_string(PEP_rating rating)
   23.59  {
   23.60 -    switch (color) {
   23.61 +    switch (rating) {
   23.62      case PEP_rating_cannot_decrypt:
   23.63          return "cannot_decrypt";
   23.64      case PEP_rating_have_no_key:
   23.65 @@ -636,7 +645,7 @@
   23.66  
   23.67  static void decorate_message(
   23.68      message *msg,
   23.69 -    PEP_color color,
   23.70 +    PEP_rating rating,
   23.71      stringlist_t *keylist
   23.72      )
   23.73  {
   23.74 @@ -644,8 +653,8 @@
   23.75  
   23.76      add_opt_field(msg, "X-pEp-Version", PEP_VERSION);
   23.77      
   23.78 -    if (color != PEP_rating_undefined)
   23.79 -        add_opt_field(msg, "X-EncStatus", color_to_string(color));
   23.80 +    if (rating != PEP_rating_undefined)
   23.81 +        add_opt_field(msg, "X-EncStatus", rating_to_string(rating));
   23.82  
   23.83      if (keylist) {
   23.84          char *_keylist = keylist_to_string(keylist);
   23.85 @@ -654,7 +663,7 @@
   23.86      }
   23.87  }
   23.88  
   23.89 -static PEP_color _rating(PEP_comm_type ct, PEP_color color)
   23.90 +static PEP_rating _rating(PEP_comm_type ct, PEP_rating rating)
   23.91  {
   23.92      if (ct == PEP_ct_unknown)
   23.93          return PEP_rating_undefined;
   23.94 @@ -665,18 +674,18 @@
   23.95      else if (ct == PEP_ct_mistrusted)
   23.96          return PEP_rating_mistrust;
   23.97      
   23.98 -    if (color == PEP_rating_unencrypted_for_some)
   23.99 +    if (rating == PEP_rating_unencrypted_for_some)
  23.100          return PEP_rating_unencrypted_for_some;
  23.101  
  23.102      if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel ||
  23.103              ct == PEP_ct_my_key_not_included) {
  23.104 -        if (color > PEP_rating_unencrypted_for_some)
  23.105 +        if (rating > PEP_rating_unencrypted_for_some)
  23.106              return PEP_rating_unencrypted_for_some;
  23.107          else
  23.108              return PEP_rating_unencrypted;
  23.109      }
  23.110  
  23.111 -    if (color == PEP_rating_unencrypted)
  23.112 +    if (rating == PEP_rating_unencrypted)
  23.113          return PEP_rating_unencrypted_for_some;
  23.114  
  23.115      if (ct >= PEP_ct_confirmed_enc_anon)
  23.116 @@ -749,7 +758,7 @@
  23.117      return result;
  23.118  }
  23.119  
  23.120 -static PEP_color decrypt_color(PEP_STATUS status)
  23.121 +static PEP_rating decrypt_rating(PEP_STATUS status)
  23.122  {
  23.123      switch (status) {
  23.124      case PEP_UNENCRYPTED:
  23.125 @@ -776,7 +785,7 @@
  23.126      }
  23.127  }
  23.128  
  23.129 -static PEP_color key_color(PEP_SESSION session, const char *fpr)
  23.130 +static PEP_rating key_rating(PEP_SESSION session, const char *fpr)
  23.131  {
  23.132      PEP_comm_type comm_type = PEP_ct_unknown;
  23.133  
  23.134 @@ -793,9 +802,9 @@
  23.135      return _rating(comm_type, PEP_rating_undefined);
  23.136  }
  23.137  
  23.138 -static PEP_color keylist_color(PEP_SESSION session, stringlist_t *keylist)
  23.139 +static PEP_rating keylist_rating(PEP_SESSION session, stringlist_t *keylist)
  23.140  {
  23.141 -    PEP_color color = PEP_rating_reliable;
  23.142 +    PEP_rating rating = PEP_rating_reliable;
  23.143  
  23.144      assert(keylist && keylist->value);
  23.145      if (keylist == NULL || keylist->value == NULL)
  23.146 @@ -806,29 +815,33 @@
  23.147          PEP_comm_type ct;
  23.148          PEP_STATUS status;
  23.149  
  23.150 -        PEP_color _color = key_color(session, _kl->value);
  23.151 -        if (_color <= PEP_rating_mistrust)
  23.152 -            return _color;
  23.153 +        PEP_rating _rating_ = key_rating(session, _kl->value);
  23.154 +        if (_rating_ <= PEP_rating_mistrust)
  23.155 +            return _rating_;
  23.156  
  23.157 -        if (color == PEP_rating_undefined)
  23.158 -            color = _color;
  23.159 +        if (rating == PEP_rating_undefined)
  23.160 +            rating = _rating_;
  23.161  
  23.162 -        if (_color >= PEP_rating_reliable) {
  23.163 +        if (_rating_ >= PEP_rating_reliable) {
  23.164              status = least_trust(session, _kl->value, &ct);
  23.165              if (status != PEP_STATUS_OK)
  23.166                  return PEP_rating_undefined;
  23.167 -            if (ct == PEP_ct_unknown)
  23.168 -                color = PEP_rating_unencrypted_for_some;
  23.169 -            else
  23.170 -                color = _rating(ct, color);
  23.171 +            if (ct == PEP_ct_unknown){
  23.172 +                if (rating >= PEP_rating_reliable){
  23.173 +                    rating = PEP_rating_reliable;
  23.174 +                }
  23.175 +            }
  23.176 +            else{
  23.177 +                rating = _rating(ct, rating);
  23.178 +            }
  23.179          }
  23.180 -        else if (_color == PEP_rating_unencrypted) {
  23.181 -            if (color > PEP_rating_unencrypted_for_some)
  23.182 -                color = PEP_rating_unencrypted_for_some;
  23.183 +        else if (_rating_ == PEP_rating_unencrypted) {
  23.184 +            if (rating > PEP_rating_unencrypted_for_some)
  23.185 +                rating = PEP_rating_unencrypted_for_some;
  23.186          }
  23.187      }
  23.188  
  23.189 -    return color;
  23.190 +    return rating;
  23.191  }
  23.192  
  23.193  static PEP_comm_type _get_comm_type(
  23.194 @@ -851,7 +864,7 @@
  23.195          else if (ident->comm_type == PEP_ct_mistrusted)
  23.196              return PEP_ct_mistrusted;
  23.197          else
  23.198 -            return MIN(max_comm_type, ident->comm_type);
  23.199 +            return _MIN(max_comm_type, ident->comm_type);
  23.200      }
  23.201      else {
  23.202          return PEP_ct_unknown;
  23.203 @@ -1022,7 +1035,8 @@
  23.204          message *src,
  23.205          stringlist_t * extra,
  23.206          message **dst,
  23.207 -        PEP_enc_format enc_format
  23.208 +        PEP_enc_format enc_format,
  23.209 +        PEP_encrypt_flags_t flags
  23.210      )
  23.211  {
  23.212      PEP_STATUS status = PEP_STATUS_OK;
  23.213 @@ -1345,7 +1359,7 @@
  23.214          message *src,
  23.215          message **dst,
  23.216          stringlist_t **keylist,
  23.217 -        PEP_color *color,
  23.218 +        PEP_rating *rating,
  23.219          PEP_decrypt_flags_t *flags, 
  23.220          identity_list **private_il
  23.221      )
  23.222 @@ -1363,10 +1377,10 @@
  23.223      assert(src);
  23.224      assert(dst);
  23.225      assert(keylist);
  23.226 -    assert(color);
  23.227 +    assert(rating);
  23.228      assert(flags);
  23.229  
  23.230 -    if (!(session && src && dst && keylist && color && flags))
  23.231 +    if (!(session && src && dst && keylist && rating && flags))
  23.232          return PEP_ILLEGAL_VALUE;
  23.233  
  23.234      *flags = 0;
  23.235 @@ -1384,13 +1398,25 @@
  23.236  
  23.237      *dst = NULL;
  23.238      *keylist = NULL;
  23.239 -    *color = PEP_rating_undefined;
  23.240 +    *rating = PEP_rating_undefined;
  23.241   
  23.242      switch (src->enc_format) {
  23.243          case PEP_enc_none:
  23.244 -            *color = PEP_rating_unencrypted;
  23.245 +            *rating = PEP_rating_unencrypted;
  23.246              if (imported_keys)
  23.247                  remove_attached_keys(src);
  23.248 +            if (session->retrieve_next_sync_msg) {
  23.249 +                status = receive_DeviceState_msg(session, src, *rating, *keylist);
  23.250 +                if (status == PEP_MESSAGE_CONSUMED || 
  23.251 +                    status == PEP_MESSAGE_DISCARDED) {
  23.252 +                    free_message(msg);
  23.253 +                    msg = NULL;
  23.254 +                    return status;
  23.255 +                }
  23.256 +                else if (status != PEP_STATUS_OK) {
  23.257 +                    return status;
  23.258 +                }
  23.259 +            }
  23.260              return PEP_UNENCRYPTED;
  23.261  
  23.262          case PEP_enc_PGP_MIME:
  23.263 @@ -1408,8 +1434,10 @@
  23.264      }
  23.265      status = cryptotech[crypto].decrypt_and_verify(session, ctext,
  23.266                                                     csize, &ptext, &psize, &_keylist);
  23.267 -    if (status > PEP_CANNOT_DECRYPT_UNKNOWN)
  23.268 +    if (status > PEP_CANNOT_DECRYPT_UNKNOWN){
  23.269 +        status = inject_DeviceState_event(session, CannotDecrypt, NULL, NULL);
  23.270          goto pep_error;
  23.271 +    }
  23.272  
  23.273      decrypt_status = status;
  23.274  
  23.275 @@ -1594,25 +1622,25 @@
  23.276              decrypt_status = status;
  23.277          }
  23.278          
  23.279 -        *color = decrypt_color(decrypt_status);
  23.280 +        *rating = decrypt_rating(decrypt_status);
  23.281          
  23.282 -        if (*color > PEP_rating_mistrust) {
  23.283 -            PEP_color kl_color = PEP_rating_undefined;
  23.284 +        if (*rating > PEP_rating_mistrust) {
  23.285 +            PEP_rating kl_rating = PEP_rating_undefined;
  23.286              
  23.287              if (_keylist)
  23.288 -                kl_color = keylist_color(session, _keylist);
  23.289 +                kl_rating = keylist_rating(session, _keylist);
  23.290              
  23.291 -            if (kl_color <= PEP_rating_mistrust) {
  23.292 -                *color = kl_color;
  23.293 +            if (kl_rating <= PEP_rating_mistrust) {
  23.294 +                *rating = kl_rating;
  23.295              }
  23.296 -            else if (*color >= PEP_rating_reliable &&
  23.297 -                     kl_color < PEP_rating_reliable) {
  23.298 -                *color = PEP_rating_unreliable;
  23.299 +            else if (*rating >= PEP_rating_reliable &&
  23.300 +                     kl_rating < PEP_rating_reliable) {
  23.301 +                *rating = PEP_rating_unreliable;
  23.302              }
  23.303 -            else if (*color >= PEP_rating_reliable &&
  23.304 -                     kl_color >= PEP_rating_reliable) {
  23.305 +            else if (*rating >= PEP_rating_reliable &&
  23.306 +                     kl_rating >= PEP_rating_reliable) {
  23.307                  if (!(src->from && src->from->user_id && src->from->user_id[0])) {
  23.308 -                    *color = PEP_rating_unreliable;
  23.309 +                    *rating = PEP_rating_unreliable;
  23.310                  }
  23.311                  else {
  23.312                      char *fpr = _keylist->value;
  23.313 @@ -1620,10 +1648,12 @@
  23.314                                                         src->from->user_id, src->from->username);
  23.315                      if (_from == NULL)
  23.316                          goto enomem;
  23.317 -                    status = update_identity(session, _from);
  23.318 +                    status = get_trust(session, _from);
  23.319                      if (_from->comm_type != PEP_ct_unknown)
  23.320 -                        *color = _rating(_from->comm_type, PEP_rating_undefined);
  23.321 +                        *rating = _rating(_from->comm_type, PEP_rating_undefined);
  23.322                      free_identity(_from);
  23.323 +                    if (status == PEP_CANNOT_FIND_IDENTITY)
  23.324 +                       status = PEP_STATUS_OK;
  23.325                      if (status != PEP_STATUS_OK)
  23.326                          goto pep_error;
  23.327                  }
  23.328 @@ -1632,14 +1662,14 @@
  23.329      }
  23.330      else
  23.331      {
  23.332 -        *color = decrypt_color(decrypt_status);
  23.333 +        *rating = decrypt_rating(decrypt_status);
  23.334          goto pep_error;
  23.335      }
  23.336  
  23.337      // Case of own key imported from own trusted message
  23.338      if (// Message have been reliably decrypted 
  23.339          msg &&
  23.340 -        *color >= PEP_rating_green &&
  23.341 +        *rating >= PEP_rating_trusted &&
  23.342          imported_private_key_address &&
  23.343          // to is [own]
  23.344          msg->to->ident->user_id &&
  23.345 @@ -1650,15 +1680,26 @@
  23.346      }
  23.347  
  23.348      if (msg) {
  23.349 -        decorate_message(msg, *color, _keylist);
  23.350 +        decorate_message(msg, *rating, _keylist);
  23.351          if (imported_keys)
  23.352              remove_attached_keys(msg);
  23.353 +        if (*rating >= PEP_rating_reliable && session->retrieve_next_sync_msg) {
  23.354 +            status = receive_DeviceState_msg(session, msg, *rating, _keylist);
  23.355 +            if (status == PEP_MESSAGE_CONSUMED || 
  23.356 +                status == PEP_MESSAGE_DISCARDED) {
  23.357 +                free_message(msg);
  23.358 +                msg = NULL;
  23.359 +            }
  23.360 +            else if (status != PEP_STATUS_OK){
  23.361 +                goto pep_error;
  23.362 +            }
  23.363 +        }
  23.364      }
  23.365  
  23.366      *dst = msg;
  23.367      *keylist = _keylist;
  23.368  
  23.369 -    return PEP_STATUS_OK;
  23.370 +    return status;
  23.371  
  23.372  enomem:
  23.373      status = PEP_OUT_OF_MEMORY;
  23.374 @@ -1676,11 +1717,11 @@
  23.375          message *src,
  23.376          message **dst,
  23.377          stringlist_t **keylist,
  23.378 -        PEP_color *color,
  23.379 +        PEP_rating *rating,
  23.380          PEP_decrypt_flags_t *flags 
  23.381      )
  23.382  {
  23.383 -    return _decrypt_message( session, src, dst, keylist, color, flags, NULL );
  23.384 +    return _decrypt_message( session, src, dst, keylist, rating, flags, NULL );
  23.385  }
  23.386  
  23.387  DYNAMIC_API PEP_STATUS own_message_private_key_details(
  23.388 @@ -1698,13 +1739,15 @@
  23.389  
  23.390      message *dst = NULL; 
  23.391      stringlist_t *keylist = NULL;
  23.392 -    PEP_color color;
  23.393 +    PEP_rating rating;
  23.394      PEP_decrypt_flags_t flags; 
  23.395  
  23.396      *ident = NULL;
  23.397  
  23.398      identity_list *private_il = NULL;
  23.399 -    PEP_STATUS status = _decrypt_message(session, msg,  &dst, &keylist, &color, &flags, &private_il);
  23.400 +    PEP_STATUS status = _decrypt_message(session, msg,  &dst, &keylist, &rating, &flags, &private_il);
  23.401 +    free_message(dst);
  23.402 +    free_stringlist(keylist);
  23.403  
  23.404      if (status == PEP_STATUS_OK &&
  23.405          flags & PEP_decrypt_flag_own_private_key &&
  23.406 @@ -1744,10 +1787,10 @@
  23.407      }
  23.408  }
  23.409  
  23.410 -DYNAMIC_API PEP_STATUS outgoing_message_color(
  23.411 +DYNAMIC_API PEP_STATUS outgoing_message_rating(
  23.412          PEP_SESSION session,
  23.413          message *msg,
  23.414 -        PEP_color *color
  23.415 +        PEP_rating *rating
  23.416      )
  23.417  {
  23.418      PEP_STATUS status = PEP_STATUS_OK;
  23.419 @@ -1758,15 +1801,15 @@
  23.420      assert(msg);
  23.421      assert(msg->from);
  23.422      assert(msg->dir == PEP_dir_outgoing);
  23.423 -    assert(color);
  23.424 +    assert(rating);
  23.425  
  23.426 -    if (!(session && msg && color))
  23.427 +    if (!(session && msg && rating))
  23.428          return PEP_ILLEGAL_VALUE;
  23.429  
  23.430      if (msg->from == NULL || msg->dir != PEP_dir_outgoing)
  23.431          return PEP_ILLEGAL_VALUE;
  23.432  
  23.433 -    *color = PEP_rating_undefined;
  23.434 +    *rating = PEP_rating_undefined;
  23.435  
  23.436      status = myself(session, msg->from);
  23.437      if (status != PEP_STATUS_OK)
  23.438 @@ -1782,27 +1825,27 @@
  23.439                                        &max_comm_type, &comm_type_determined);
  23.440  
  23.441      if (comm_type_determined == false)
  23.442 -        *color = PEP_rating_undefined;
  23.443 +        *rating = PEP_rating_undefined;
  23.444      else
  23.445 -        *color = MAX(_rating(max_comm_type, PEP_rating_undefined),
  23.446 +        *rating = _MAX(_rating(max_comm_type, PEP_rating_undefined),
  23.447                  PEP_rating_unencrypted);
  23.448  
  23.449      return PEP_STATUS_OK;
  23.450  }
  23.451  
  23.452 -DYNAMIC_API PEP_STATUS identity_color(
  23.453 +DYNAMIC_API PEP_STATUS identity_rating(
  23.454          PEP_SESSION session,
  23.455          pEp_identity *ident,
  23.456 -        PEP_color *color
  23.457 +        PEP_rating *rating
  23.458      )
  23.459  {
  23.460      PEP_STATUS status = PEP_STATUS_OK;
  23.461  
  23.462      assert(session);
  23.463      assert(ident);
  23.464 -    assert(color);
  23.465 +    assert(rating);
  23.466  
  23.467 -    if (!(session && ident && color))
  23.468 +    if (!(session && ident && rating))
  23.469          return PEP_ILLEGAL_VALUE;
  23.470  
  23.471      if (ident->me)
  23.472 @@ -1811,7 +1854,7 @@
  23.473          status = update_identity(session, ident);
  23.474  
  23.475      if (status == PEP_STATUS_OK)
  23.476 -        *color = _rating(ident->comm_type, PEP_rating_undefined);
  23.477 +        *rating = _rating(ident->comm_type, PEP_rating_undefined);
  23.478  
  23.479      return status;
  23.480  }
  23.481 @@ -1832,3 +1875,25 @@
  23.482      return status;
  23.483  }
  23.484  
  23.485 +
  23.486 +DYNAMIC_API PEP_color color_from_rating(PEP_rating rating)
  23.487 +{
  23.488 +    if (rating == PEP_rating_b0rken)
  23.489 +        return PEP_color_no_color;
  23.490 +
  23.491 +    if (rating < PEP_rating_undefined)
  23.492 +        return PEP_color_red;
  23.493 +
  23.494 +    if (rating < PEP_rating_reliable)
  23.495 +        return PEP_color_no_color;
  23.496 +
  23.497 +    if (rating < PEP_rating_trusted)
  23.498 +        return PEP_color_yellow;
  23.499 +
  23.500 +    if (rating >= PEP_rating_trusted)
  23.501 +        return PEP_color_green;
  23.502 +
  23.503 +    // this should never happen
  23.504 +    assert(false);
  23.505 +}
  23.506 +
    24.1 --- a/src/message_api.h	Mon Oct 03 14:34:58 2016 +0200
    24.2 +++ b/src/message_api.h	Wed Oct 05 15:38:42 2016 +0200
    24.3 @@ -17,6 +17,13 @@
    24.4      );
    24.5  void attach_own_key(PEP_SESSION session, message *msg);
    24.6  PEP_cryptotech determine_encryption_format(message *msg);
    24.7 +void add_opt_field(message *msg, const char *name, const char *value);
    24.8 +
    24.9 +typedef enum _PEP_encrypt_flags {
   24.10 +    PEP_encrypt_flag_force_encryption = 0x1
   24.11 +} PEP_encrypt_flags; 
   24.12 +
   24.13 +typedef unsigned int PEP_encrypt_flags_t;
   24.14  
   24.15  // encrypt_message() - encrypt message in memory
   24.16  //
   24.17 @@ -26,6 +33,7 @@
   24.18  //      extra (in)          extra keys for encryption
   24.19  //      dst (out)           pointer to new encrypted message or NULL on failure
   24.20  //      enc_format (in)     encrypted format
   24.21 +//      flags (in)          flags to set special encryption features
   24.22  //
   24.23  //  return value:
   24.24  //      PEP_STATUS_OK                   on success
   24.25 @@ -44,7 +52,8 @@
   24.26          message *src,
   24.27          stringlist_t *extra,
   24.28          message **dst,
   24.29 -        PEP_enc_format enc_format
   24.30 +        PEP_enc_format enc_format,
   24.31 +        PEP_encrypt_flags_t flags
   24.32      );
   24.33  
   24.34  // encrypt_message_for_self() - encrypt message in memory for user's identity only,
   24.35 @@ -80,7 +89,7 @@
   24.36          PEP_enc_format enc_format
   24.37      );
   24.38  
   24.39 -typedef enum _PEP_color {
   24.40 +typedef enum _PEP_rating {
   24.41      PEP_rating_undefined = 0,
   24.42      PEP_rating_cannot_decrypt,
   24.43      PEP_rating_have_no_key,
   24.44 @@ -88,23 +97,36 @@
   24.45      PEP_rating_unencrypted_for_some,
   24.46      PEP_rating_unreliable,
   24.47      PEP_rating_reliable,
   24.48 -    PEP_rating_yellow = PEP_rating_reliable,
   24.49      PEP_rating_trusted,
   24.50 -    PEP_rating_green = PEP_rating_trusted,
   24.51      PEP_rating_trusted_and_anonymized,
   24.52      PEP_rating_fully_anonymous,   
   24.53  
   24.54      PEP_rating_mistrust = -1,
   24.55 -    PEP_rating_red = PEP_rating_mistrust,
   24.56      PEP_rating_b0rken = -2,
   24.57      PEP_rating_under_attack = -3
   24.58 +} PEP_rating;
   24.59 +
   24.60 +typedef enum _PEP_color {
   24.61 +    PEP_color_no_color = 0,
   24.62 +    PEP_color_yellow,
   24.63 +    PEP_color_green,
   24.64 +    PEP_color_red = -1,
   24.65  } PEP_color;
   24.66  
   24.67 +// color_from_rating - calculate color from rating
   24.68 +//
   24.69 +//  parameters:
   24.70 +//      rating (in)         rating
   24.71 +//
   24.72 +//  return value:           color representing that rating
   24.73 +
   24.74 +DYNAMIC_API PEP_color color_from_rating(PEP_rating rating);
   24.75 +
   24.76  typedef enum _PEP_decrypt_flags {
   24.77      PEP_decrypt_flag_own_private_key = 0x1
   24.78  } PEP_decrypt_flags; 
   24.79  
   24.80 -typedef uint32_t PEP_decrypt_flags_t;
   24.81 +typedef unsigned int PEP_decrypt_flags_t;
   24.82  
   24.83  // decrypt_message() - decrypt message in memory
   24.84  //
   24.85 @@ -113,8 +135,8 @@
   24.86  //      src (in)            message to decrypt
   24.87  //      dst (out)           pointer to new decrypted message or NULL on failure
   24.88  //      keylist (out)       stringlist with keyids
   24.89 -//      color (out)         color for the message
   24.90 -//      flags (out)         flags to signal special message features
   24.91 +//      rating (out)        rating for the message
   24.92 +//      flags (out)         flags to signal special decryption features
   24.93  //
   24.94  //  return value:
   24.95  //      error status or PEP_STATUS_OK on success
   24.96 @@ -131,8 +153,8 @@
   24.97          message *src,
   24.98          message **dst,
   24.99          stringlist_t **keylist,
  24.100 -        PEP_color *color,
  24.101 -        PEP_decrypt_flags_t *flags 
  24.102 +        PEP_rating *rating,
  24.103 +        PEP_decrypt_flags_t *flags
  24.104  );
  24.105  
  24.106  // own_message_private_key_details() - details on own key in own message
  24.107 @@ -162,12 +184,12 @@
  24.108          pEp_identity **ident 
  24.109  );
  24.110  
  24.111 -// outgoing_message_color() - get color for an outgoing message
  24.112 +// outgoing_message_rating() - get rating for an outgoing message
  24.113  //
  24.114  //  parameters:
  24.115  //      session (in)        session handle
  24.116 -//      msg (in)            message to get the color for
  24.117 -//      color (out)         color for the message
  24.118 +//      msg (in)            message to get the rating for
  24.119 +//      rating (out)        rating for the message
  24.120  //
  24.121  //  return value:
  24.122  //      error status or PEP_STATUS_OK on success
  24.123 @@ -177,19 +199,19 @@
  24.124  //      msg->dir must be PEP_dir_outgoing
  24.125  //      the ownership of msg remains with the caller
  24.126  
  24.127 -DYNAMIC_API PEP_STATUS outgoing_message_color(
  24.128 +DYNAMIC_API PEP_STATUS outgoing_message_rating(
  24.129          PEP_SESSION session,
  24.130          message *msg,
  24.131 -        PEP_color *color
  24.132 +        PEP_rating *rating
  24.133      );
  24.134  
  24.135  
  24.136 -// identity_color() - get color for a single identity
  24.137 +// identity_rating() - get rating for a single identity
  24.138  //
  24.139  //  parameters:
  24.140  //      session (in)        session handle
  24.141 -//      ident (in)          identity to get the color for
  24.142 -//      color (out)         color for the identity
  24.143 +//      ident (in)          identity to get the rating for
  24.144 +//      rating (out)        rating for the identity
  24.145  //
  24.146  //  return value:
  24.147  //      error status or PEP_STATUS_OK on success
  24.148 @@ -197,10 +219,10 @@
  24.149  //  caveat:
  24.150  //      the ownership of ident remains with the caller
  24.151  
  24.152 -DYNAMIC_API PEP_STATUS identity_color(
  24.153 +DYNAMIC_API PEP_STATUS identity_rating(
  24.154          PEP_SESSION session,
  24.155          pEp_identity *ident,
  24.156 -        PEP_color *color
  24.157 +        PEP_rating *rating
  24.158      );
  24.159  
  24.160  
    25.1 --- a/src/mime.c	Mon Oct 03 14:34:58 2016 +0200
    25.2 +++ b/src/mime.c	Wed Oct 05 15:38:42 2016 +0200
    25.3 @@ -173,7 +173,6 @@
    25.4      PEP_STATUS status = PEP_STATUS_OK;
    25.5      struct mailmime * mime = NULL;
    25.6      char * mime_type;
    25.7 -
    25.8      assert(blob);
    25.9      assert(result);
   25.10  
   25.11 @@ -210,7 +209,8 @@
   25.12      char *_username = NULL;
   25.13      struct mailimf_mailbox *mb;
   25.14  
   25.15 -    _username = mailmime_encode_subject_header("utf-8", ident->username, 0);
   25.16 +    _username = ident->username ? mailmime_encode_subject_header("utf-8",
   25.17 +            ident->username, 0) : strdup("");
   25.18      if (_username == NULL)
   25.19          goto enomem;
   25.20  
   25.21 @@ -281,7 +281,7 @@
   25.22          goto enomem;
   25.23  
   25.24      identity_list *_il;
   25.25 -    for (_il = il; _il; _il = _il->next) {
   25.26 +    for (_il = il; _il && _il->ident; _il = _il->next) {
   25.27          mb = identity_to_mailbox(_il->ident);
   25.28          if (mb == NULL)
   25.29              goto enomem;
    26.1 --- a/src/openpgp_compat.c	Mon Oct 03 14:34:58 2016 +0200
    26.2 +++ b/src/openpgp_compat.c	Wed Oct 05 15:38:42 2016 +0200
    26.3 @@ -20,4 +20,5 @@
    26.4          *keyinfo_list = _keyinfo_list;
    26.5      
    26.6      return retval;
    26.7 -}
    26.8 \ No newline at end of file
    26.9 +}
   26.10 +
    27.1 --- a/src/openpgp_compat.h	Mon Oct 03 14:34:58 2016 +0200
    27.2 +++ b/src/openpgp_compat.h	Wed Oct 05 15:38:42 2016 +0200
    27.3 @@ -41,4 +41,5 @@
    27.4      
    27.5  #ifdef __cplusplus
    27.6  }
    27.7 -#endif
    27.8 \ No newline at end of file
    27.9 +#endif
   27.10 +
    28.1 --- a/src/pEpEngine.c	Mon Oct 03 14:34:58 2016 +0200
    28.2 +++ b/src/pEpEngine.c	Wed Oct 05 15:38:42 2016 +0200
    28.3 @@ -3,6 +3,7 @@
    28.4  #include "cryptotech.h"
    28.5  #include "transport.h"
    28.6  #include "blacklist.h"
    28.7 +#include "sync_fsm.h"
    28.8  
    28.9  static int init_count = -1;
   28.10  
   28.11 @@ -27,6 +28,8 @@
   28.12      static const char *sql_trustword;
   28.13      static const char *sql_get_identity;
   28.14      static const char *sql_set_person;
   28.15 +    static const char *sql_set_device_group;
   28.16 +    static const char *sql_get_device_group;
   28.17      static const char *sql_set_pgp_keypair;
   28.18      static const char *sql_set_identity;
   28.19      static const char *sql_set_identity_flags;
   28.20 @@ -46,11 +49,12 @@
   28.21  
   28.22      // Own keys
   28.23      static const char *sql_own_key_is_listed;
   28.24 -    static const char *sql_own_key_retrieve;
   28.25 +    static const char *sql_own_identities_retrieve;
   28.26  
   28.27      // Sequence
   28.28      static const char *sql_sequence_value1;
   28.29      static const char *sql_sequence_value2;
   28.30 +    static const char *sql_sequence_value3;
   28.31  
   28.32      // Revocation tracking
   28.33      static const char *sql_set_revoked;
   28.34 @@ -127,14 +131,15 @@
   28.35      sqlite3_busy_timeout(_session->system_db, 1000);
   28.36  
   28.37  // increment this when patching DDL
   28.38 -#define _DDL_USER_VERSION "1"
   28.39 +#define _DDL_USER_VERSION "3"
   28.40  
   28.41      if (in_first) {
   28.42 +
   28.43          int_result = sqlite3_exec(
   28.44              _session->db,
   28.45 -                "create table version_info (\n"
   28.46 +                "create table if not exists version_info (\n"
   28.47                  "   id integer primary key,\n"
   28.48 -                "   timestamp integer default (datetime('now')) ,\n"
   28.49 +                "   timestamp integer default (datetime('now')),\n"
   28.50                  "   version text,\n"
   28.51                  "   comment text\n"
   28.52                  ");\n",
   28.53 @@ -142,23 +147,11 @@
   28.54                  NULL,
   28.55                  NULL
   28.56          );
   28.57 -        if (int_result == SQLITE_OK) {
   28.58 -            int_result = sqlite3_exec(
   28.59 -                _session->db,
   28.60 -                "pragma user_version = "_DDL_USER_VERSION";\n"
   28.61 -                "insert or replace into version_info (id, version)"
   28.62 -                    "values (1, '" PEP_ENGINE_VERSION "');",
   28.63 -                NULL,
   28.64 -                NULL,
   28.65 -                NULL
   28.66 -            );
   28.67 -            assert(int_result == SQLITE_OK);
   28.68 -        }
   28.69 -
   28.70          int_result = sqlite3_exec(
   28.71              _session->db,
   28.72 +                "PRAGMA application_id = 0x23423423;\n"
   28.73                  "create table if not exists log (\n"
   28.74 -                "   timestamp integer default (datetime('now')) ,\n"
   28.75 +                "   timestamp integer default (datetime('now')),\n"
   28.76                  "   title text not null,\n"
   28.77                  "   entity text not null,\n"
   28.78                  "   description text,\n"
   28.79 @@ -173,7 +166,8 @@
   28.80                  "   private_id text,\n"
   28.81                  "   created integer,\n"
   28.82                  "   expires integer,\n"
   28.83 -                "   comment text\n"
   28.84 +                "   comment text,\n"
   28.85 +                "   flags integer default 0\n"
   28.86                  ");\n"
   28.87                  "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   28.88                  "   expires\n"
   28.89 @@ -185,7 +179,8 @@
   28.90                  "       references pgp_keypair (fpr)\n"
   28.91                  "       on delete set null,\n"
   28.92                  "   lang text,\n"
   28.93 -                "   comment text\n"
   28.94 +                "   comment text,\n"
   28.95 +                "   device_group text\n"
   28.96                  ");\n"
   28.97                  "create table if not exists identity (\n"
   28.98                  "   address text,\n"
   28.99 @@ -196,7 +191,7 @@
  28.100                  "       references pgp_keypair (fpr)\n"
  28.101                  "       on delete set null,\n"
  28.102                  "   comment text,\n"
  28.103 -                "   flags integer default (0),"
  28.104 +                "   flags integer default 0,"
  28.105                  "   primary key (address, user_id)\n"
  28.106                  ");\n"
  28.107                  "create table if not exists trust (\n"
  28.108 @@ -217,7 +212,8 @@
  28.109                  // sequences
  28.110                  "create table if not exists sequences(\n"
  28.111                  "   name text primary key,\n"
  28.112 -                "   value integer default 0\n"
  28.113 +                "   value integer default 0,\n"
  28.114 +                "   own integer default 0\n"
  28.115                  ");\n"
  28.116                  "create table if not exists revoked_keys (\n"
  28.117                  "   revoked_fpr text primary key,\n"
  28.118 @@ -247,12 +243,35 @@
  28.119              int_result = sqlite3_exec(
  28.120                  _session->db,
  28.121                  "alter table identity\n"
  28.122 -                "   add column flags integer default (0);",
  28.123 +                "   add column flags integer default 0;\n",
  28.124                  NULL,
  28.125                  NULL,
  28.126                  NULL
  28.127              );
  28.128 -            assert(int_result == SQLITE_OK);
  28.129 +        }
  28.130 +
  28.131 +        if (version < 2) {
  28.132 +            int_result = sqlite3_exec(
  28.133 +                _session->db,
  28.134 +                "alter table pgp_keypair\n"
  28.135 +                "   add column flags integer default 0;\n"
  28.136 +                "alter table person\n"
  28.137 +                "   add column device_group text;\n",
  28.138 +                NULL,
  28.139 +                NULL,
  28.140 +                NULL
  28.141 +            );
  28.142 +        }
  28.143 +
  28.144 +        if (version < 3) {
  28.145 +            int_result = sqlite3_exec(
  28.146 +                _session->db,
  28.147 +                "alter table sequences\n"
  28.148 +                "   add column own integer default 0;\n",
  28.149 +                NULL,
  28.150 +                NULL,
  28.151 +                NULL
  28.152 +            );
  28.153          }
  28.154  
  28.155          if (version < atoi(_DDL_USER_VERSION)) {
  28.156 @@ -268,10 +287,24 @@
  28.157              assert(int_result == SQLITE_OK);
  28.158          }
  28.159  
  28.160 +        if (version <= atoi(_DDL_USER_VERSION)) {
  28.161 +            int_result = sqlite3_exec(
  28.162 +                _session->db,
  28.163 +                "pragma user_version = "_DDL_USER_VERSION";\n"
  28.164 +                "insert or replace into version_info (id, version)"
  28.165 +                    "values (1, '" PEP_ENGINE_VERSION "');",
  28.166 +                NULL,
  28.167 +                NULL,
  28.168 +                NULL
  28.169 +            );
  28.170 +            assert(int_result == SQLITE_OK);
  28.171 +        }
  28.172 +
  28.173          sql_log = "insert into log (title, entity, description, comment)"
  28.174                    "values (?1, ?2, ?3, ?4);";
  28.175  
  28.176 -        sql_get_identity =  "select fpr, username, comm_type, lang, flags"
  28.177 +        sql_get_identity =  "select fpr, username, comm_type, lang,"
  28.178 +                            "   identity.flags | pgp_keypair.flags"
  28.179                              "   from identity"
  28.180                              "   join person on id = identity.user_id"
  28.181                              "   join pgp_keypair on fpr = identity.main_key_id"
  28.182 @@ -289,14 +322,20 @@
  28.183                           "    (select coalesce((select main_key_id from person "
  28.184                           "      where id = ?1), upper(replace(?4,' ',''))))) ;";
  28.185  
  28.186 +        sql_set_device_group = "update person set device_group = ?1 "
  28.187 +                               "where id = '" PEP_OWN_USERID "';";
  28.188 +
  28.189 +        sql_get_device_group = "select device_group from person "
  28.190 +                               "where id = '" PEP_OWN_USERID "';";
  28.191 +
  28.192          sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
  28.193                                "values (upper(replace(?1,' ',''))) ;";
  28.194  
  28.195          sql_set_identity = "insert or replace into identity (address, main_key_id, "
  28.196                             "user_id, flags) values (?1, upper(replace(?2,' ','')),"
  28.197 -                           "?3, ?4) ;";
  28.198 +                           "?3, ?4 & 255) ;";
  28.199  
  28.200 -        sql_set_identity_flags = "update identity set flags = ?1 "
  28.201 +        sql_set_identity_flags = "update identity set flags = ?1 & 255 "
  28.202                                   "where address = ?2 and user_id = ?3 ;";
  28.203  
  28.204          sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
  28.205 @@ -341,19 +380,21 @@
  28.206                                  "   where main_key_id = upper(replace(?1,' ',''))"
  28.207                                  "    and user_id = '" PEP_OWN_USERID "' );";
  28.208  
  28.209 -        sql_own_key_retrieve = "select main_key_id from person "
  28.210 -                               "  where main_key_id is not null"
  28.211 -                               "   and id = '" PEP_OWN_USERID "' "
  28.212 -                               "union "
  28.213 -                               " select main_key_id from identity "
  28.214 -                               "  where main_key_id is not null"
  28.215 -                               "   and user_id = '" PEP_OWN_USERID "' ;";
  28.216 +        sql_own_identities_retrieve =  "select address, fpr, username, "
  28.217 +                            "   lang, identity.flags | pgp_keypair.flags"
  28.218 +                            "   from identity"
  28.219 +                            "   join person on id = identity.user_id"
  28.220 +                            "   join pgp_keypair on fpr = identity.main_key_id"
  28.221 +                            "   join trust on id = trust.user_id"
  28.222 +                            "       and pgp_keypair_fpr = identity.main_key_id"
  28.223 +                            "   where identity.user_id = '" PEP_OWN_USERID "';";
  28.224          
  28.225 -        sql_sequence_value1 = "insert or replace into sequences (name, value) "
  28.226 +        sql_sequence_value1 = "insert or replace into sequences (name, value, own) "
  28.227                                "values (?1, "
  28.228                                "(select coalesce((select value + 1 from sequences "
  28.229 -                              "where name = ?1), 1 ))) ; ";
  28.230 -        sql_sequence_value2 = "select value from sequences where name = ?1 ;";
  28.231 +                              "where name = ?1), 1 )), ?2) ; ";
  28.232 +        sql_sequence_value2 = "select value, own from sequences where name = ?1 ;";
  28.233 +        sql_sequence_value3 = "update sequences set value = ?2, own = ?3 where name = ?1 ;";
  28.234          
  28.235          sql_set_revoked =     "insert or replace into revoked_keys ("
  28.236                                "    revoked_fpr, replacement_fpr, revocation_date) "
  28.237 @@ -365,8 +406,8 @@
  28.238                                "    where replacement_fpr = upper(replace(?1,' ','')) ;";
  28.239      }
  28.240  
  28.241 -    int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log),
  28.242 -            &_session->log, NULL);
  28.243 +    int_result = sqlite3_prepare_v2(_session->db, sql_log,
  28.244 +            (int)strlen(sql_log), &_session->log, NULL);
  28.245      assert(int_result == SQLITE_OK);
  28.246  
  28.247      int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  28.248 @@ -381,8 +422,17 @@
  28.249              (int)strlen(sql_set_person), &_session->set_person, NULL);
  28.250      assert(int_result == SQLITE_OK);
  28.251  
  28.252 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  28.253 +            (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  28.254 +    assert(int_result == SQLITE_OK);
  28.255 +
  28.256 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  28.257 +            (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  28.258 +    assert(int_result == SQLITE_OK);
  28.259 +
  28.260      int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  28.261 -            (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair, NULL);
  28.262 +            (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  28.263 +            NULL);
  28.264      assert(int_result == SQLITE_OK);
  28.265  
  28.266      int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
  28.267 @@ -390,7 +440,8 @@
  28.268      assert(int_result == SQLITE_OK);
  28.269  
  28.270      int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  28.271 -            (int)strlen(sql_set_identity_flags), &_session->set_identity_flags, NULL);
  28.272 +            (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  28.273 +            NULL);
  28.274      assert(int_result == SQLITE_OK);
  28.275  
  28.276      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  28.277 @@ -406,7 +457,8 @@
  28.278      assert(int_result == SQLITE_OK);
  28.279  
  28.280      int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
  28.281 -            (int)strlen(sql_mark_as_compromized), &_session->mark_compromized, NULL);
  28.282 +            (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
  28.283 +            NULL);
  28.284      assert(int_result == SQLITE_OK);
  28.285  
  28.286      int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  28.287 @@ -428,45 +480,57 @@
  28.288      assert(int_result == SQLITE_OK);
  28.289  
  28.290      int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  28.291 -            (int)strlen(sql_blacklist_delete), &_session->blacklist_delete, NULL);
  28.292 +            (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  28.293 +            NULL);
  28.294      assert(int_result == SQLITE_OK);
  28.295  
  28.296      int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  28.297 -            (int)strlen(sql_blacklist_is_listed), &_session->blacklist_is_listed, NULL);
  28.298 +            (int)strlen(sql_blacklist_is_listed),
  28.299 +            &_session->blacklist_is_listed, NULL);
  28.300      assert(int_result == SQLITE_OK);
  28.301  
  28.302      int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  28.303 -            (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve, NULL);
  28.304 +            (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  28.305 +            NULL);
  28.306      assert(int_result == SQLITE_OK);
  28.307  
  28.308      // Own keys
  28.309      
  28.310      int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  28.311 -            (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed, NULL);
  28.312 +            (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  28.313 +            NULL);
  28.314      assert(int_result == SQLITE_OK);
  28.315      
  28.316 -    int_result = sqlite3_prepare_v2(_session->db, sql_own_key_retrieve,
  28.317 -            (int)strlen(sql_own_key_retrieve), &_session->own_key_retrieve, NULL);
  28.318 +    int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  28.319 +            (int)strlen(sql_own_identities_retrieve),
  28.320 +            &_session->own_identities_retrieve, NULL);
  28.321      assert(int_result == SQLITE_OK);
  28.322   
  28.323      // Sequence
  28.324  
  28.325      int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  28.326 -            (int)strlen(sql_sequence_value1), &_session->sequence_value1, NULL);
  28.327 +            (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  28.328 +            NULL);
  28.329      assert(int_result == SQLITE_OK);
  28.330  
  28.331      int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  28.332 -            (int)strlen(sql_sequence_value2), &_session->sequence_value2, NULL);
  28.333 +            (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  28.334 +            NULL);
  28.335 +    assert(int_result == SQLITE_OK);
  28.336 +
  28.337 +    int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
  28.338 +            (int)strlen(sql_sequence_value3), &_session->sequence_value3,
  28.339 +            NULL);
  28.340      assert(int_result == SQLITE_OK);
  28.341  
  28.342      // Revocation tracking
  28.343      
  28.344      int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  28.345 -                                    (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  28.346 +            (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  28.347      assert(int_result == SQLITE_OK);
  28.348      
  28.349      int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  28.350 -                                    (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  28.351 +            (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  28.352      assert(int_result == SQLITE_OK);
  28.353      
  28.354      status = init_cryptotech(_session, in_first);
  28.355 @@ -483,8 +547,6 @@
  28.356  
  28.357      // runtime config
  28.358  
  28.359 -    _session->passive_mode = false;
  28.360 -    _session->unencrypted_subject = false;
  28.361  #ifdef ANDROID
  28.362      _session->use_only_own_private_keys = true;
  28.363  #elif TARGET_OS_IPHONE
  28.364 @@ -522,6 +584,9 @@
  28.365      --init_count;
  28.366  
  28.367      if (session) {
  28.368 +        if (session->sync_state != DeviceState_state_NONE)
  28.369 +            unregister_sync_callbacks(session);
  28.370 +
  28.371          if (session->db) {
  28.372              if (session->log)
  28.373                  sqlite3_finalize(session->log);
  28.374 @@ -531,6 +596,10 @@
  28.375                  sqlite3_finalize(session->get_identity);
  28.376              if (session->set_person)
  28.377                  sqlite3_finalize(session->set_person);
  28.378 +            if (session->set_device_group)
  28.379 +                sqlite3_finalize(session->set_device_group);
  28.380 +            if (session->get_device_group)
  28.381 +                sqlite3_finalize(session->get_device_group);
  28.382              if (session->set_pgp_keypair)
  28.383                  sqlite3_finalize(session->set_pgp_keypair);
  28.384              if (session->set_identity)
  28.385 @@ -561,12 +630,14 @@
  28.386                  sqlite3_finalize(session->blacklist_retrieve);
  28.387              if (session->own_key_is_listed)
  28.388                  sqlite3_finalize(session->own_key_is_listed);
  28.389 -            if (session->own_key_retrieve)
  28.390 -                sqlite3_finalize(session->own_key_retrieve);
  28.391 +            if (session->own_identities_retrieve)
  28.392 +                sqlite3_finalize(session->own_identities_retrieve);
  28.393              if (session->sequence_value1)
  28.394                  sqlite3_finalize(session->sequence_value1);
  28.395              if (session->sequence_value2)
  28.396                  sqlite3_finalize(session->sequence_value2);
  28.397 +            if (session->sequence_value3)
  28.398 +                sqlite3_finalize(session->sequence_value3);
  28.399              if (session->set_revoked)
  28.400                  sqlite3_finalize(session->set_revoked);
  28.401              if (session->get_revoked)
  28.402 @@ -597,12 +668,19 @@
  28.403      session->unencrypted_subject = enable;
  28.404  }
  28.405  
  28.406 -DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable)
  28.407 +DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session,
  28.408 +        bool enable)
  28.409  {
  28.410      assert(session);
  28.411      session->use_only_own_private_keys = enable;
  28.412  }
  28.413  
  28.414 +DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  28.415 +{
  28.416 +    assert(session);
  28.417 +    session->keep_sync_msg = enable;
  28.418 +}
  28.419 +
  28.420  DYNAMIC_API PEP_STATUS log_event(
  28.421          PEP_SESSION session,
  28.422          const char *title,
  28.423 @@ -697,7 +775,6 @@
  28.424      char *buffer;
  28.425      char *dest;
  28.426      size_t fsize;
  28.427 -    PEP_STATUS _status;
  28.428  
  28.429      assert(session);
  28.430      assert(fingerprint);
  28.431 @@ -730,6 +807,7 @@
  28.432  
  28.433      int n_words = 0;
  28.434      while (source < fingerprint + fsize) {
  28.435 +        PEP_STATUS _status;
  28.436          uint16_t value;
  28.437          char *word;
  28.438          size_t _wsize;
  28.439 @@ -828,7 +906,8 @@
  28.440  {
  28.441      assert(src);
  28.442  
  28.443 -    pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id, src->username);
  28.444 +    pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  28.445 +            src->username);
  28.446      assert(dup);
  28.447      if (dup == NULL)
  28.448          return NULL;
  28.449 @@ -891,8 +970,10 @@
  28.450          if (_identity == NULL)
  28.451              return PEP_OUT_OF_MEMORY;
  28.452  
  28.453 -        _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
  28.454 -        const char* const _lang = (const char *) sqlite3_column_text(session->get_identity, 3);
  28.455 +        _identity->comm_type = (PEP_comm_type)
  28.456 +            sqlite3_column_int(session->get_identity, 2);
  28.457 +        const char* const _lang = (const char *)
  28.458 +            sqlite3_column_text(session->get_identity, 3);
  28.459          if (_lang && _lang[0]) {
  28.460              assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  28.461              assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  28.462 @@ -901,7 +982,8 @@
  28.463              _identity->lang[1] = _lang[1];
  28.464              _identity->lang[2] = 0;
  28.465          }
  28.466 -        _identity->flags = (unsigned int) sqlite3_column_int(session->get_identity, 4);
  28.467 +        _identity->flags = (unsigned int)
  28.468 +            sqlite3_column_int(session->get_identity, 4);
  28.469          *identity = _identity;
  28.470          break;
  28.471      default:
  28.472 @@ -943,13 +1025,19 @@
  28.473  
  28.474      sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
  28.475  
  28.476 +    if (identity->lang[0]) {
  28.477 +        assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  28.478 +        assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  28.479 +        assert(identity->lang[2] == 0);
  28.480 +    }
  28.481 +
  28.482      sqlite3_reset(session->set_person);
  28.483      sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
  28.484              SQLITE_STATIC);
  28.485      sqlite3_bind_text(session->set_person, 2, identity->username, -1,
  28.486              SQLITE_STATIC);
  28.487      if (identity->lang[0])
  28.488 -        sqlite3_bind_text(session->set_person, 3, identity->lang, 1,
  28.489 +        sqlite3_bind_text(session->set_person, 3, identity->lang, 2,
  28.490                  SQLITE_STATIC);
  28.491      else
  28.492          sqlite3_bind_null(session->set_person, 3);
  28.493 @@ -1007,6 +1095,61 @@
  28.494          return PEP_COMMIT_FAILED;
  28.495  }
  28.496  
  28.497 +DYNAMIC_API PEP_STATUS set_device_group(
  28.498 +        PEP_SESSION session,
  28.499 +        const char *group_name
  28.500 +    )
  28.501 +{
  28.502 +    int result;
  28.503 +
  28.504 +    assert(session);
  28.505 +    assert(group_name);
  28.506 +
  28.507 +    if (!(session && group_name))
  28.508 +        return PEP_ILLEGAL_VALUE;
  28.509 +
  28.510 +    sqlite3_reset(session->set_device_group);
  28.511 +    sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  28.512 +            SQLITE_STATIC);
  28.513 +    result = sqlite3_step(session->set_device_group);
  28.514 +    sqlite3_reset(session->set_device_group);
  28.515 +    if (result != SQLITE_DONE)
  28.516 +        return PEP_CANNOT_SET_PERSON;
  28.517 +
  28.518 +    return PEP_STATUS_OK;
  28.519 +}
  28.520 +
  28.521 +DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  28.522 +{
  28.523 +    PEP_STATUS status = PEP_STATUS_OK;
  28.524 +    int result;
  28.525 +
  28.526 +    assert(session);
  28.527 +    assert(group_name);
  28.528 +
  28.529 +    if (!(session && group_name))
  28.530 +        return PEP_ILLEGAL_VALUE;
  28.531 +
  28.532 +    sqlite3_reset(session->get_device_group);
  28.533 +
  28.534 +    result = sqlite3_step(session->get_device_group);
  28.535 +    switch (result) {
  28.536 +    case SQLITE_ROW: {
  28.537 +        *group_name = strdup(
  28.538 +            (const char *) sqlite3_column_text(session->get_device_group, 0));
  28.539 +            if(*group_name == NULL)
  28.540 +                status = PEP_OUT_OF_MEMORY;
  28.541 +        break;
  28.542 +    }
  28.543 + 
  28.544 +    default:
  28.545 +        status = PEP_RECORD_NOT_FOUND;
  28.546 +    }
  28.547 +
  28.548 +    sqlite3_reset(session->get_device_group);
  28.549 +    return status;
  28.550 +}
  28.551 +
  28.552  DYNAMIC_API PEP_STATUS set_identity_flags(
  28.553          PEP_SESSION session,
  28.554          pEp_identity *identity,
  28.555 @@ -1087,13 +1230,15 @@
  28.556      identity->comm_type = PEP_ct_unknown;
  28.557  
  28.558      sqlite3_reset(session->get_trust);
  28.559 -    sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1, SQLITE_STATIC);
  28.560 +    sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  28.561 +            SQLITE_STATIC);
  28.562      sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  28.563  
  28.564      result = sqlite3_step(session->get_trust);
  28.565      switch (result) {
  28.566      case SQLITE_ROW: {
  28.567 -        int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
  28.568 +        int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  28.569 +                0);
  28.570          identity->comm_type = comm_type;
  28.571          break;
  28.572      }
  28.573 @@ -1154,10 +1299,11 @@
  28.574      assert(psize);
  28.575      assert(keylist);
  28.576  
  28.577 -    if (!(session && ctext && csize && ptext && psize && keylist && keylist))
  28.578 +    if (!(session && ctext && csize && ptext && psize && keylist))
  28.579          return PEP_ILLEGAL_VALUE;
  28.580  
  28.581 -    return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(session, ctext, csize, ptext, psize, keylist);
  28.582 +    return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  28.583 +            session, ctext, csize, ptext, psize, keylist);
  28.584  }
  28.585  
  28.586  DYNAMIC_API PEP_STATUS encrypt_and_sign(
  28.587 @@ -1175,7 +1321,8 @@
  28.588      if (!(session && keylist && ptext && psize && ctext && csize))
  28.589          return PEP_ILLEGAL_VALUE;
  28.590  
  28.591 -    return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session, keylist, ptext, psize, ctext, csize);
  28.592 +    return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  28.593 +            keylist, ptext, psize, ctext, csize);
  28.594  }
  28.595  
  28.596  DYNAMIC_API PEP_STATUS verify_text(
  28.597 @@ -1193,7 +1340,8 @@
  28.598      if (!(session && text && size && signature && sig_size && keylist))
  28.599          return PEP_ILLEGAL_VALUE;
  28.600  
  28.601 -    return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text, size, signature, sig_size, keylist);
  28.602 +    return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  28.603 +            size, signature, sig_size, keylist);
  28.604  }
  28.605  
  28.606  DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  28.607 @@ -1219,7 +1367,28 @@
  28.608      if (!(session && fpr && key_data && size))
  28.609          return PEP_ILLEGAL_VALUE;
  28.610  
  28.611 -    return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr, key_data, size);
  28.612 +    return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  28.613 +            key_data, size, false);
  28.614 +}
  28.615 +
  28.616 +DYNAMIC_API PEP_STATUS export_secrect_key(
  28.617 +        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  28.618 +    )
  28.619 +{
  28.620 +    assert(session);
  28.621 +    assert(fpr);
  28.622 +    assert(key_data);
  28.623 +    assert(size);
  28.624 +
  28.625 +    if (!(session && fpr && key_data && size))
  28.626 +        return PEP_ILLEGAL_VALUE;
  28.627 +
  28.628 +    // don't accept key IDs but full fingerprints only
  28.629 +    if (strlen(fpr) < 16)
  28.630 +        return PEP_ILLEGAL_VALUE;
  28.631 +
  28.632 +    return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  28.633 +            key_data, size, true);
  28.634  }
  28.635  
  28.636  DYNAMIC_API PEP_STATUS find_keys(
  28.637 @@ -1233,7 +1402,8 @@
  28.638      if (!(session && pattern && keylist))
  28.639          return PEP_ILLEGAL_VALUE;
  28.640  
  28.641 -    return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
  28.642 +    return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  28.643 +            keylist);
  28.644  }
  28.645  
  28.646  
  28.647 @@ -1248,10 +1418,17 @@
  28.648      assert(identity->username);
  28.649  
  28.650      if (!(session && identity && identity->address &&
  28.651 -        (identity->fpr == NULL || identity->fpr[0] == 0) && identity->username))
  28.652 +            (identity->fpr == NULL || identity->fpr[0] == 0) &&
  28.653 +            identity->username))
  28.654          return PEP_ILLEGAL_VALUE;
  28.655  
  28.656 -    return session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session, identity);
  28.657 +    PEP_STATUS status =
  28.658 +        session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  28.659 +                identity);
  28.660 +    if (status != PEP_STATUS_OK)
  28.661 +        return status;
  28.662 +
  28.663 +    return status;
  28.664  }
  28.665  
  28.666  DYNAMIC_API PEP_STATUS get_key_rating(
  28.667 @@ -1267,7 +1444,8 @@
  28.668      if (!(session && fpr && comm_type))
  28.669          return PEP_ILLEGAL_VALUE;
  28.670  
  28.671 -    return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr, comm_type);
  28.672 +    return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  28.673 +            comm_type);
  28.674  }
  28.675  
  28.676  DYNAMIC_API PEP_STATUS import_key(
  28.677 @@ -1283,7 +1461,8 @@
  28.678      if (!(session && key_data))
  28.679          return PEP_ILLEGAL_VALUE;
  28.680  
  28.681 -    return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data, size, private_keys);
  28.682 +    return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  28.683 +            size, private_keys);
  28.684  }
  28.685  
  28.686  DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  28.687 @@ -1358,10 +1537,10 @@
  28.688  }
  28.689  
  28.690  DYNAMIC_API PEP_STATUS key_revoked(
  28.691 -                                   PEP_SESSION session,
  28.692 -                                   const char *fpr,
  28.693 -                                   bool *revoked
  28.694 -                                   )
  28.695 +       PEP_SESSION session,
  28.696 +       const char *fpr,
  28.697 +       bool *revoked
  28.698 +   )
  28.699  {
  28.700      assert(session);
  28.701      assert(fpr);
  28.702 @@ -1371,7 +1550,7 @@
  28.703          return PEP_ILLEGAL_VALUE;
  28.704      
  28.705      return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  28.706 -                                                              revoked);
  28.707 +            revoked);
  28.708  }
  28.709  
  28.710  static void _clean_log_value(char *text)
  28.711 @@ -1443,11 +1622,16 @@
  28.712          result = sqlite3_step(session->crashdump);
  28.713          switch (result) {
  28.714          case SQLITE_ROW:
  28.715 -            timestamp = (const char *) sqlite3_column_text(session->crashdump, 0);
  28.716 -            title   = (const char *) sqlite3_column_text(session->crashdump, 1);
  28.717 -            entity  = (const char *) sqlite3_column_text(session->crashdump, 2);
  28.718 -            desc    = (const char *) sqlite3_column_text(session->crashdump, 3);
  28.719 -            comment = (const char *) sqlite3_column_text(session->crashdump, 4);
  28.720 +            timestamp = (const char *) sqlite3_column_text(session->crashdump,
  28.721 +                    0);
  28.722 +            title   = (const char *) sqlite3_column_text(session->crashdump,
  28.723 +                    1);
  28.724 +            entity  = (const char *) sqlite3_column_text(session->crashdump,
  28.725 +                    2);
  28.726 +            desc    = (const char *) sqlite3_column_text(session->crashdump,
  28.727 +                    3);
  28.728 +            comment = (const char *) sqlite3_column_text(session->crashdump,
  28.729 +                    4);
  28.730  
  28.731              _logdata = _concat_string(_logdata, timestamp, ',');
  28.732              if (_logdata == NULL)
  28.733 @@ -1522,9 +1706,12 @@
  28.734          result = sqlite3_step(session->languagelist);
  28.735          switch (result) {
  28.736          case SQLITE_ROW:
  28.737 -            lang = (const char *) sqlite3_column_text(session->languagelist, 0);
  28.738 -            name = (const char *) sqlite3_column_text(session->languagelist, 1);
  28.739 -            phrase = (const char *) sqlite3_column_text(session->languagelist, 2);
  28.740 +            lang = (const char *) sqlite3_column_text(session->languagelist,
  28.741 +                    0);
  28.742 +            name = (const char *) sqlite3_column_text(session->languagelist,
  28.743 +                    1);
  28.744 +            phrase = (const char *) sqlite3_column_text(session->languagelist,
  28.745 +                    2);
  28.746  
  28.747              _languages = _concat_string(_languages, lang, ',');
  28.748              if (_languages == NULL)
  28.749 @@ -1614,47 +1801,128 @@
  28.750      return status;
  28.751  }
  28.752  
  28.753 +static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  28.754 +        int32_t *value)
  28.755 +{
  28.756 +    assert(session && name && value);
  28.757 +    if (!(session && name && value))
  28.758 +        return PEP_ILLEGAL_VALUE;
  28.759 +
  28.760 +    PEP_STATUS status = PEP_STATUS_OK;
  28.761 +
  28.762 +    sqlite3_reset(session->sequence_value2);
  28.763 +    sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  28.764 +            SQLITE_STATIC);
  28.765 +    int result = sqlite3_step(session->sequence_value2);
  28.766 +    switch (result) {
  28.767 +        case SQLITE_ROW: {
  28.768 +            int32_t _value = (int32_t)
  28.769 +                    sqlite3_column_int(session->sequence_value2, 0);
  28.770 +            int _own = (int)
  28.771 +                    sqlite3_column_int(session->sequence_value2, 1);
  28.772 +            *value = _value;
  28.773 +            if (_own)
  28.774 +                status = PEP_OWN_SEQUENCE;
  28.775 +            break;
  28.776 +        }
  28.777 +        case SQLITE_DONE:
  28.778 +            status = PEP_RECORD_NOT_FOUND;
  28.779 +            break;
  28.780 +        default:
  28.781 +            status = PEP_UNKNOWN_ERROR;
  28.782 +    }
  28.783 +    sqlite3_reset(session->sequence_value2);
  28.784 +
  28.785 +    return status;
  28.786 +}
  28.787 +
  28.788 +static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  28.789 +        const char *name, int own)
  28.790 +{
  28.791 +    assert(session && name);
  28.792 +    if (!(session && name))
  28.793 +        return PEP_ILLEGAL_VALUE;
  28.794 +
  28.795 +    sqlite3_reset(session->sequence_value1);
  28.796 +    sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  28.797 +    sqlite3_bind_int(session->sequence_value1, 2, own);
  28.798 +    int result = sqlite3_step(session->sequence_value1);
  28.799 +    assert(result == SQLITE_DONE);
  28.800 +    sqlite3_reset(session->sequence_value1);
  28.801 +    if (result == SQLITE_DONE)
  28.802 +        return PEP_STATUS_OK;
  28.803 +    else
  28.804 +        return PEP_CANNOT_INCREASE_SEQUENCE;
  28.805 +}
  28.806 +
  28.807 +static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  28.808 +        const char *name, int32_t value, int own)
  28.809 +{
  28.810 +    assert(session && name && value > 0);
  28.811 +    if (!(session && name && value > 0))
  28.812 +        return PEP_ILLEGAL_VALUE;
  28.813 +
  28.814 +    sqlite3_reset(session->sequence_value3);
  28.815 +    sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  28.816 +    sqlite3_bind_int(session->sequence_value3, 2, value);
  28.817 +    sqlite3_bind_int(session->sequence_value3, 3, own);
  28.818 +    int result = sqlite3_step(session->sequence_value3);
  28.819 +    assert(result == SQLITE_DONE);
  28.820 +    sqlite3_reset(session->sequence_value3);
  28.821 +    if (result == SQLITE_DONE)
  28.822 +        return PEP_STATUS_OK;
  28.823 +    else
  28.824 +        return PEP_CANNOT_SET_SEQUENCE_VALUE;
  28.825 +}
  28.826 +
  28.827  DYNAMIC_API PEP_STATUS sequence_value(
  28.828          PEP_SESSION session,
  28.829 -        const char *name,
  28.830 +        char *name,
  28.831          int32_t *value
  28.832      )
  28.833  {
  28.834      PEP_STATUS status = PEP_STATUS_OK;
  28.835 -    int result;
  28.836  
  28.837      assert(session);
  28.838 -    assert(name);
  28.839 -    assert(value);
  28.840 +    assert(name && value && *value >= 0);
  28.841  
  28.842 -    if (!(session && name && value))
  28.843 +    if (!(session && name && value && *value >= 0))
  28.844          return PEP_ILLEGAL_VALUE;
  28.845  
  28.846 -    *value = 0;
  28.847 -
  28.848 -    sqlite3_reset(session->sequence_value1);
  28.849 -    sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  28.850 -    result = sqlite3_step(session->sequence_value1);
  28.851 -    assert(result == SQLITE_DONE);
  28.852 -    sqlite3_reset(session->sequence_value1);
  28.853 -    if (result != SQLITE_DONE) {
  28.854 -        status = PEP_UNKNOWN_ERROR;
  28.855 +    int own = 0;
  28.856 +    if (!name[0]) {
  28.857 +        unsigned char uuid[16];
  28.858 +        uuid_generate_random(uuid);
  28.859 +        uuid_unparse_upper(uuid, name);
  28.860 +        own = 1;
  28.861      }
  28.862      else {
  28.863 -        sqlite3_reset(session->sequence_value2);
  28.864 -        sqlite3_bind_text(session->sequence_value2, 1, name, -1, SQLITE_STATIC);
  28.865 -        result = sqlite3_step(session->sequence_value2);
  28.866 -        switch (result) {
  28.867 -            case SQLITE_ROW: {
  28.868 -                int32_t _value = (int32_t)
  28.869 -                        sqlite3_column_int64(session->sequence_value2, 0);
  28.870 -                *value = _value;
  28.871 -                break;
  28.872 -            }
  28.873 -            default:
  28.874 -                status = PEP_UNKNOWN_ERROR;
  28.875 +        if (name == session->sync_uuid || strcmp(name, session->sync_uuid) == 0)
  28.876 +            own = 1;
  28.877 +    }
  28.878 +
  28.879 +    if (*value) {
  28.880 +        int32_t old_value = 0;
  28.881 +        status = _get_sequence_value(session, name, &old_value);
  28.882 +        if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  28.883 +            return status;
  28.884 +
  28.885 +        if (old_value >= *value) {
  28.886 +            return PEP_SEQUENCE_VIOLATED;
  28.887          }
  28.888 -        sqlite3_reset(session->sequence_value2);
  28.889 +        else {
  28.890 +            status = _set_sequence_value(session, name, *value, own);
  28.891 +            return status;
  28.892 +        }
  28.893 +    }
  28.894 +
  28.895 +    assert(*value == 0);
  28.896 +    status = _increment_sequence_value(session, name, own);
  28.897 +    if (status == PEP_STATUS_OK) {
  28.898 +        status = _get_sequence_value(session, name, value);
  28.899 +        assert(*value < INT32_MAX);
  28.900 +        if (*value == INT32_MAX)
  28.901 +            return PEP_CANNOT_INCREASE_SEQUENCE;
  28.902      }
  28.903      return status;
  28.904  }
  28.905 @@ -1681,7 +1949,8 @@
  28.906      
  28.907      sqlite3_reset(session->set_revoked);
  28.908      sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  28.909 -    sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1, SQLITE_STATIC);
  28.910 +    sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  28.911 +            SQLITE_STATIC);
  28.912      sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  28.913  
  28.914      int result;
  28.915 @@ -1731,9 +2000,11 @@
  28.916      result = sqlite3_step(session->get_revoked);
  28.917      switch (result) {
  28.918          case SQLITE_ROW: {
  28.919 -            *revoked_fpr = strdup((const char *) sqlite3_column_text(session->get_revoked, 0));
  28.920 +            *revoked_fpr = strdup((const char *)
  28.921 +                    sqlite3_column_text(session->get_revoked, 0));
  28.922              if(*revoked_fpr)
  28.923 -                *revocation_date = sqlite3_column_int64(session->get_revoked, 1);
  28.924 +                *revocation_date = sqlite3_column_int64(session->get_revoked,
  28.925 +                        1);
  28.926              else
  28.927                  status = PEP_OUT_OF_MEMORY;
  28.928  
  28.929 @@ -1748,6 +2019,20 @@
  28.930      return status;
  28.931  }
  28.932  
  28.933 +PEP_STATUS key_created(
  28.934 +        PEP_SESSION session,
  28.935 +        const char *fpr,
  28.936 +        time_t *created
  28.937 +    )
  28.938 +{
  28.939 +    assert(session && fpr && created);
  28.940 +    if (!(session && fpr && created))
  28.941 +        return PEP_ILLEGAL_VALUE;
  28.942 +
  28.943 +    return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  28.944 +            created);
  28.945 +}
  28.946 +
  28.947  DYNAMIC_API const char* get_engine_version() {
  28.948      return PEP_ENGINE_VERSION;
  28.949  }
    29.1 --- a/src/pEpEngine.h	Mon Oct 03 14:34:58 2016 +0200
    29.2 +++ b/src/pEpEngine.h	Wed Oct 05 15:38:42 2016 +0200
    29.3 @@ -42,6 +42,7 @@
    29.4      PEP_KEY_NOT_FOUND                               = 0x0201,
    29.5      PEP_KEY_HAS_AMBIG_NAME                          = 0x0202,
    29.6      PEP_GET_KEY_FAILED                              = 0x0203,
    29.7 +    PEP_CANNOT_EXPORT_KEY                           = 0x0204,
    29.8      
    29.9      PEP_CANNOT_FIND_IDENTITY                        = 0x0301,
   29.10      PEP_CANNOT_SET_PERSON                           = 0x0381,
   29.11 @@ -73,9 +74,26 @@
   29.12      PEP_CANNOT_ENCODE                               = 0x0803,
   29.13  
   29.14      PEP_SYNC_NO_TRUSTWORDS_CALLBACK                 = 0x0901,
   29.15 +    PEP_SYNC_ILLEGAL_MESSAGE                        = 0x0902,
   29.16 +    PEP_SYNC_NO_INJECT_CALLBACK                     = 0x0903,
   29.17 +
   29.18 +    PEP_SEQUENCE_VIOLATED                           = 0x0970,
   29.19 +    PEP_CANNOT_INCREASE_SEQUENCE                    = 0x0971,
   29.20 +    PEP_CANNOT_SET_SEQUENCE_VALUE                   = 0x0972,
   29.21 +    PEP_OWN_SEQUENCE                                = 0x097f,
   29.22 +
   29.23 +    PEP_SYNC_STATEMACHINE_ERROR                     = 0x0980,
   29.24 +    PEP_SYNC_NO_TRUST                               = 0x0981,
   29.25 +    PEP_STATEMACHINE_INVALID_STATE                  = 0x0982,
   29.26 +    PEP_STATEMACHINE_INVALID_EVENT                  = 0x0983,
   29.27 +    PEP_STATEMACHINE_INVALID_CONDITION              = 0x0984,
   29.28 +    PEP_STATEMACHINE_INVALID_ACTION                 = 0x0985,
   29.29  
   29.30      PEP_COMMIT_FAILED                               = 0xff01,
   29.31 +    PEP_MESSAGE_CONSUMED                            = 0xff02,
   29.32 +    PEP_MESSAGE_DISCARDED                           = 0xff03,
   29.33  
   29.34 +    PEP_RECORD_NOT_FOUND                            = -6,
   29.35      PEP_CANNOT_CREATE_TEMP_FILE                     = -5,
   29.36      PEP_ILLEGAL_VALUE                               = -4,
   29.37      PEP_BUFFER_TOO_SMALL                            = -3,
   29.38 @@ -151,6 +169,14 @@
   29.39  DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable);
   29.40  
   29.41  
   29.42 +// config_keep_sync_msg() - do not remove sync messages (for debugging purposes)
   29.43 +//
   29.44 +//      session (in)    session handle
   29.45 +//      enable (in)     flag if enabled or disabled
   29.46 +
   29.47 +DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable);
   29.48 +
   29.49 +
   29.50  // decrypt_and_verify() - decrypt and/or verify a message
   29.51  //
   29.52  //    parameters:
   29.53 @@ -320,6 +346,8 @@
   29.54      );
   29.55  
   29.56  
   29.57 +// TODO: increase versions in pEp.asn1 if rating changes
   29.58 +
   29.59  typedef enum _PEP_comm_type {
   29.60      PEP_ct_unknown = 0,
   29.61  
   29.62 @@ -381,10 +409,16 @@
   29.63  } PEP_comm_type;
   29.64  
   29.65  typedef enum _identity_flags {
   29.66 +    // the first octet flags are app defined settings
   29.67      PEP_idf_not_for_sync = 1,   // don't use this identity for sync
   29.68 -    PEP_idf_group = 2           // identity of group of persons
   29.69 +    PEP_idf_list = 2,           // identity of list of persons
   29.70 +
   29.71 +    // the second octet flags are calculated
   29.72 +    PEP_idf_devicegroup = 256   // identity of a device group member
   29.73  } identity_flags;
   29.74  
   29.75 +typedef unsigned int identity_flags_t;
   29.76 +
   29.77  typedef struct _pEp_identity {
   29.78      char *address;              // C string with address UTF-8 encoded
   29.79      char *fpr;                  // C string with fingerprint UTF-8 encoded
   29.80 @@ -394,7 +428,7 @@
   29.81      char lang[3];               // language of conversation
   29.82                                  // ISO 639-1 ALPHA-2, last byte is 0
   29.83      bool me;                    // if this is the local user herself/himself
   29.84 -    unsigned int flags;         // identity_flag1 | identity_flag2 | ...
   29.85 +    identity_flags_t flags;     // identity_flag1 | identity_flag2 | ...
   29.86  } pEp_identity;
   29.87  
   29.88  typedef struct _identity_list {
   29.89 @@ -462,8 +496,8 @@
   29.90  //                            NULL if failure
   29.91  //
   29.92  //    caveat:
   29.93 -//        the address string is being copied; the original string remains in the
   29.94 -//        ownership of the caller
   29.95 +//        address and user_id are being copied; the original strings remains in
   29.96 +//        the ownership of the caller
   29.97  //        the resulting pEp_identity structure goes to the ownership of the
   29.98  //        caller and has to be freed with free_identity() when not in use any
   29.99  //        more
  29.100 @@ -496,6 +530,38 @@
  29.101          PEP_SESSION session, const pEp_identity *identity
  29.102      );
  29.103  
  29.104 +// set_device_group() - update own person's device group
  29.105 +//
  29.106 +//    parameters:
  29.107 +//        session (in)        session handle
  29.108 +//        group_name (in)     new group name
  29.109 +//
  29.110 +//    return value:
  29.111 +//        PEP_STATUS_OK = 0             device group was updated
  29.112 +//        PEP_CANNOT_SET_PERSON         update failed
  29.113 +
  29.114 +DYNAMIC_API PEP_STATUS set_device_group(
  29.115 +        PEP_SESSION session,
  29.116 +        const char *group_name
  29.117 +    );
  29.118 +
  29.119 +// get_device_group() - get own person's device group
  29.120 +//
  29.121 +//    parameters:
  29.122 +//        session (in)        session handle
  29.123 +//        group_name (in)     new group name
  29.124 +//
  29.125 +//    return value:
  29.126 +//        PEP_STATUS_OK = 0             couldn't get device group
  29.127 +//        PEP_RECORD_NOT_FOUND          update failed
  29.128 +//
  29.129 +//    caveat:
  29.130 +//        the ownerships of group_name is going to the caller
  29.131 +
  29.132 +DYNAMIC_API PEP_STATUS get_device_group(
  29.133 +        PEP_SESSION session, 
  29.134 +        char **group_name
  29.135 +    );
  29.136  
  29.137  // set_identity_flags() - update identity flags on existing identity
  29.138  //
  29.139 @@ -618,6 +684,30 @@
  29.140      );
  29.141  
  29.142  
  29.143 +// export_secret_key() - export secret key ascii armored
  29.144 +//
  29.145 +//  parameters:
  29.146 +//      session (in)            session handle
  29.147 +//      fpr (in)                fingerprint of key, at least 16 hex digits
  29.148 +//      key_data (out)          ASCII armored OpenPGP secret key
  29.149 +//      size (out)              amount of data to handle
  29.150 +//
  29.151 +//  return value:
  29.152 +//      PEP_STATUS_OK = 0       key was successfully exported
  29.153 +//      PEP_OUT_OF_MEMORY       out of memory
  29.154 +//      PEP_KEY_NOT_FOUND       key not found
  29.155 +//      PEP_CANNOT_EXPORT_KEY   cannot export secret key (i.e. it's on an HKS)
  29.156 +//
  29.157 +//  caveat:
  29.158 +//      the key_data goes to the ownership of the caller
  29.159 +//      the caller is responsible to free() it (on Windoze use pEp_free())
  29.160 +//      beware of leaking secret key data - overwrite it in memory after use
  29.161 +
  29.162 +DYNAMIC_API PEP_STATUS export_secrect_key(
  29.163 +        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  29.164 +    );
  29.165 +
  29.166 +
  29.167  // recv_key() - update key(s) from keyserver
  29.168  //
  29.169  //  parameters:
  29.170 @@ -743,7 +833,7 @@
  29.171  //  caveat:
  29.172  //      reason text must not include empty lines
  29.173  //      this function is meant for internal use only; better use
  29.174 -//      key_compromized() of keymanagement API
  29.175 +//      key_mistrusted() of keymanagement API
  29.176  
  29.177  DYNAMIC_API PEP_STATUS revoke_key(
  29.178          PEP_SESSION session,
  29.179 @@ -843,16 +933,24 @@
  29.180  //
  29.181  //  parameters:
  29.182  //      session (in)            session handle
  29.183 -//      name (in)               name of sequence
  29.184 -//      value (out)             value of sequence
  29.185 +//      name (inout)            name of sequence or char[37] set to {0, }
  29.186 +//                              for new own sequence named as UUID
  29.187 +//      value (inout)           value of sequence value to test or 0 for
  29.188 +//                              getting next value
  29.189 +//
  29.190 +//  returns:
  29.191 +//      PEP_STATUS_OK                   no error, not own sequence
  29.192 +//      PEP_SEQUENCE_VIOLATED           if sequence violated
  29.193 +//      PEP_CANNOT_INCREASE_SEQUENCE    if sequence cannot be increased
  29.194 +//      PEP_OWN_SEQUENCE                if own sequence
  29.195  
  29.196  DYNAMIC_API PEP_STATUS sequence_value(
  29.197          PEP_SESSION session,
  29.198 -        const char *name,
  29.199 +        char *name,
  29.200          int32_t *value
  29.201      );
  29.202  
  29.203 -    
  29.204 +
  29.205  // set_revoked() - records relation between a revoked key and its replacement
  29.206  //
  29.207  //  parameters:
  29.208 @@ -868,6 +966,7 @@
  29.209         const uint64_t revocation_date
  29.210      );
  29.211  
  29.212 +
  29.213  // get_revoked() - find revoked key that may have been replaced by given key, if any
  29.214  //
  29.215  //  parameters:
  29.216 @@ -884,6 +983,20 @@
  29.217      );
  29.218  
  29.219  
  29.220 +// key_created() - get creation date of a key
  29.221 +//
  29.222 +//  parameters:
  29.223 +//      session (in)            session handle
  29.224 +//      fpr (in)                fingerprint of key
  29.225 +//      created (out)           date of creation
  29.226 +
  29.227 +PEP_STATUS key_created(
  29.228 +        PEP_SESSION session,
  29.229 +        const char *fpr,
  29.230 +        time_t *created
  29.231 +    );
  29.232 +
  29.233 +
  29.234  // get_engine_version() - returns the current version of pEpEngine (this is different
  29.235  //                        from the pEp protocol version!)
  29.236  //
    30.1 --- a/src/pEp_internal.h	Mon Oct 03 14:34:58 2016 +0200
    30.2 +++ b/src/pEp_internal.h	Wed Oct 05 15:38:42 2016 +0200
    30.3 @@ -95,6 +95,8 @@
    30.4      sqlite3_stmt *trustword;
    30.5      sqlite3_stmt *get_identity;
    30.6      sqlite3_stmt *set_person;
    30.7 +    sqlite3_stmt *set_device_group;
    30.8 +    sqlite3_stmt *get_device_group;
    30.9      sqlite3_stmt *set_pgp_keypair;
   30.10      sqlite3_stmt *set_identity;
   30.11      sqlite3_stmt *set_identity_flags;
   30.12 @@ -115,13 +117,14 @@
   30.13      
   30.14      // Own keys
   30.15      sqlite3_stmt *own_key_is_listed;
   30.16 -    sqlite3_stmt *own_key_retrieve;
   30.17 +    sqlite3_stmt *own_identities_retrieve;
   30.18  
   30.19      // sequence value
   30.20      sqlite3_stmt *sequence_value1;
   30.21      sqlite3_stmt *sequence_value2;
   30.22 +    sqlite3_stmt *sequence_value3;
   30.23  
   30.24 -    // sequence value
   30.25 +    // revoked keys
   30.26      sqlite3_stmt *set_revoked;
   30.27      sqlite3_stmt *get_revoked;
   30.28  
   30.29 @@ -131,15 +134,19 @@
   30.30      void *sync_obj;
   30.31      messageToSend_t messageToSend;
   30.32      showHandshake_t showHandshake;
   30.33 +    inject_sync_msg_t inject_sync_msg;
   30.34 +    retrieve_next_sync_msg_t retrieve_next_sync_msg;
   30.35  
   30.36 -    // state machines
   30.37 +    // key sync
   30.38      DeviceState_state sync_state;
   30.39 +    char sync_uuid[37];
   30.40  
   30.41      // runtime config
   30.42  
   30.43      bool passive_mode;
   30.44      bool unencrypted_subject;
   30.45      bool use_only_own_private_keys;
   30.46 +    bool keep_sync_msg;
   30.47      
   30.48  } pEpSession;
   30.49  
    31.1 --- a/src/pgp_gpg.c	Mon Oct 03 14:34:58 2016 +0200
    31.2 +++ b/src/pgp_gpg.c	Wed Oct 05 15:38:42 2016 +0200
    31.3 @@ -1152,7 +1152,8 @@
    31.4  }
    31.5  
    31.6  PEP_STATUS pgp_export_keydata(
    31.7 -    PEP_SESSION session, const char *fpr, char **key_data, size_t *size
    31.8 +        PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
    31.9 +        bool secret
   31.10      )
   31.11  {
   31.12      gpgme_error_t gpgme_error;
   31.13 @@ -1182,8 +1183,12 @@
   31.14          return PEP_UNKNOWN_ERROR;
   31.15      }
   31.16  
   31.17 -    gpgme_error = gpg.gpgme_op_export(session->ctx, fpr,
   31.18 -        GPGME_EXPORT_MODE_MINIMAL, dh);
   31.19 +    if (secret)
   31.20 +        gpgme_error = gpg.gpgme_op_export(session->ctx, fpr,
   31.21 +            GPGME_EXPORT_MODE_SECRET, dh);
   31.22 +    else
   31.23 +        gpgme_error = gpg.gpgme_op_export(session->ctx, fpr,
   31.24 +            GPGME_EXPORT_MODE_MINIMAL, dh);
   31.25      gpgme_error = _GPGERR(gpgme_error);
   31.26      switch (gpgme_error) {
   31.27      case GPG_ERR_NO_ERROR:
   31.28 @@ -1271,25 +1276,13 @@
   31.29  
   31.30                  // first subkey is primary key
   31.31                  char* fpr = key->subkeys->fpr;
   31.32 +                char* uid = key->uids->uid;
   31.33  
   31.34                  assert(fpr);
   31.35 +                assert(uid);
   31.36                  if (!fpr)
   31.37                      return PEP_GET_KEY_FAILED;
   31.38                  
   31.39 -                bool own_key = false;
   31.40 -                PEP_STATUS own_key_status = own_key_is_listed(session, fpr, &own_key);
   31.41 -                
   31.42 -                if (own_key || own_key_status != PEP_STATUS_OK) // Hrm... is this second part ok?
   31.43 -                    continue;
   31.44 -
   31.45 -                char* uid = key->uids->uid;
   31.46 -                assert(uid); // ??                
   31.47 -                
   31.48 -                
   31.49 -                PEP_STATUS key_status = PEP_GET_KEY_FAILED;
   31.50 -                
   31.51 -                bool key_revoked = false;
   31.52 -                                
   31.53                  if (key->subkeys->revoked)
   31.54                      continue;
   31.55                  
   31.56 @@ -2068,6 +2061,38 @@
   31.57      return status;
   31.58  }
   31.59  
   31.60 +PEP_STATUS pgp_key_created(
   31.61 +        PEP_SESSION session,
   31.62 +        const char *fpr,
   31.63 +        time_t *created
   31.64 +    )
   31.65 +{
   31.66 +    PEP_STATUS status = PEP_STATUS_OK;
   31.67 +    gpgme_key_t key;
   31.68 +
   31.69 +    assert(session);
   31.70 +    assert(fpr);
   31.71 +    assert(created);
   31.72 +
   31.73 +    *created = 0;
   31.74 +
   31.75 +    status = find_single_key(session, fpr, &key);
   31.76 +    if (status != PEP_STATUS_OK)
   31.77 +        return status;
   31.78 +
   31.79 +    if (key && key->subkeys)
   31.80 +    {
   31.81 +        *created = (time_t) key->subkeys->timestamp;
   31.82 +    }
   31.83 +    else
   31.84 +    {
   31.85 +        status = PEP_KEY_NOT_FOUND;
   31.86 +    }
   31.87 +
   31.88 +    gpg.gpgme_key_unref(key);
   31.89 +    return status;
   31.90 +}
   31.91 +
   31.92  PEP_STATUS pgp_binary(const char **path)
   31.93  {
   31.94      assert(path);
    32.1 --- a/src/pgp_gpg.h	Mon Oct 03 14:34:58 2016 +0200
    32.2 +++ b/src/pgp_gpg.h	Wed Oct 05 15:38:42 2016 +0200
    32.3 @@ -23,7 +23,8 @@
    32.4  PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr);
    32.5  
    32.6  PEP_STATUS pgp_export_keydata(
    32.7 -        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
    32.8 +        PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
    32.9 +        bool secret
   32.10      );
   32.11  
   32.12  PEP_STATUS pgp_find_keys(
   32.13 @@ -78,6 +79,12 @@
   32.14          bool *revoked
   32.15      );
   32.16  
   32.17 +PEP_STATUS pgp_key_created(
   32.18 +        PEP_SESSION session,
   32.19 +        const char *fpr,
   32.20 +        time_t *created
   32.21 +    );
   32.22 +
   32.23  PEP_STATUS pgp_binary(const char **path);
   32.24  #define PGP_BINARY_PATH pgp_binary
   32.25  
    33.1 --- a/src/pgp_netpgp.c	Mon Oct 03 14:34:58 2016 +0200
    33.2 +++ b/src/pgp_netpgp.c	Wed Oct 05 15:38:42 2016 +0200
    33.3 @@ -1673,6 +1673,60 @@
    33.4      return PEP_STATUS_OK;
    33.5  }
    33.6  
    33.7 +PEP_STATUS pgp_key_created(
    33.8 +        PEP_SESSION session,
    33.9 +        const char *fprstr,
   33.10 +        time_t *created
   33.11 +    )
   33.12 +{
   33.13 +    uint8_t fpr[PGP_FINGERPRINT_SIZE];
   33.14 +    pgp_key_t *key;
   33.15 +    size_t length;
   33.16 +    unsigned from = 0;
   33.17 +
   33.18 +    PEP_STATUS status = PEP_STATUS_OK;
   33.19 +
   33.20 +    assert(session);
   33.21 +    assert(fprstr);
   33.22 +    assert(created);
   33.23 +
   33.24 +    if (!session || !fprstr || !created)
   33.25 +        return PEP_UNKNOWN_ERROR;
   33.26 +
   33.27 +    *created = 0;
   33.28 +
   33.29 +    if(pthread_mutex_lock(&netpgp_mutex)){
   33.30 +        return PEP_UNKNOWN_ERROR;
   33.31 +    }
   33.32 +
   33.33 +    if (!str_to_fpr(fprstr, fpr, &length)) {
   33.34 +        status = PEP_ILLEGAL_VALUE;
   33.35 +        goto unlock_netpgp;
   33.36 +    }
   33.37 +        
   33.38 +    key = pgp_getkeybyfpr(
   33.39 +           netpgp.io,
   33.40 +           netpgp.pubring,
   33.41 +           fpr, length, &from, NULL,0,0);
   33.42 +
   33.43 +    if (key)
   33.44 +    {
   33.45 +        *created = (time_t) key->key.pubkey.birthtime;
   33.46 +    }
   33.47 +    else
   33.48 +    {
   33.49 +        status = PEP_KEY_NOT_FOUND;
   33.50 +        goto unlock_netpgp;
   33.51 +    }
   33.52 +    
   33.53 +
   33.54 +
   33.55 +unlock_netpgp:
   33.56 +    pthread_mutex_unlock(&netpgp_mutex);
   33.57 +
   33.58 +    return status;
   33.59 +}
   33.60 +
   33.61  
   33.62  PEP_STATUS pgp_list_keyinfo(
   33.63          PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list)
   33.64 @@ -1700,5 +1754,3 @@
   33.65      
   33.66      return result;
   33.67  }
   33.68 -
   33.69 -
    34.1 --- a/src/pgp_netpgp.h	Mon Oct 03 14:34:58 2016 +0200
    34.2 +++ b/src/pgp_netpgp.h	Wed Oct 05 15:38:42 2016 +0200
    34.3 @@ -74,3 +74,10 @@
    34.4          const char *fpr,
    34.5          bool *revoked
    34.6      );
    34.7 +
    34.8 +PEP_STATUS pgp_key_created(
    34.9 +        PEP_SESSION session,
   34.10 +        const char *fprstr,
   34.11 +        time_t *created
   34.12 +    );
   34.13 +
    35.1 --- a/src/platform_unix.c	Mon Oct 03 14:34:58 2016 +0200
    35.2 +++ b/src/platform_unix.c	Wed Oct 05 15:38:42 2016 +0200
    35.3 @@ -1,5 +1,6 @@
    35.4  #define _POSIX_C_SOURCE 200809L
    35.5  
    35.6 +#include <time.h>
    35.7  #include <string.h>
    35.8  #include <stdlib.h>
    35.9  #include <assert.h>
   35.10 @@ -11,7 +12,9 @@
   35.11  #include "platform_unix.h"
   35.12  
   35.13  #define MAX_PATH 1024
   35.14 +#ifndef LOCAL_DB_FILENAME
   35.15  #define LOCAL_DB_FILENAME ".pEp_management.db"
   35.16 +#endif
   35.17  #define SYSTEM_DB_FILENAME "system.db"
   35.18  
   35.19  #ifndef bool
   35.20 @@ -21,6 +24,7 @@
   35.21  #endif
   35.22  
   35.23  #ifdef ANDROID
   35.24 +#include <uuid.h>
   35.25  char *stpncpy(char *dst, const char *src, size_t n)
   35.26  {
   35.27      if (n != 0) {
   35.28 @@ -93,6 +97,49 @@
   35.29      }
   35.30      return buffer;
   35.31  }
   35.32 +
   35.33 +// TODO: Check and possibly fix this function if necessary
   35.34 +void uuid_generate_random(pEpUUID out)
   35.35 +{
   35.36 +    uuid_t *uuid;
   35.37 +    uuid_rc_t rc_create;
   35.38 +
   35.39 +    if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
   35.40 +        uuid_make(uuid, UUID_MAKE_V1) != UUID_RC_OK ||
   35.41 +        uuid_export(uuid, UUID_FMT_BIN, out, NULL) != UUID_RC_OK)
   35.42 +    {
   35.43 +        memset(out, 0, sizeof(pEpUUID));
   35.44 +    }
   35.45 +
   35.46 +    if (rc_create == UUID_RC_OK)
   35.47 +    {
   35.48 +        uuid_destroy(uuid);
   35.49 +    }
   35.50 +}
   35.51 +
   35.52 +// TODO: Check and possibly fix this function if necessary
   35.53 +void uuid_unparse_upper(pEpUUID uu, uuid_string_t out)
   35.54 +{
   35.55 +    uuid_t *uuid;
   35.56 +    uuid_rc_t rc_create;
   35.57 +
   35.58 +    if ((rc_create = uuid_create(&uuid)) != UUID_RC_OK ||
   35.59 +        uuid_import(uuid, UUID_FMT_BIN, uu, sizeof(uuid__t)) != UUID_RC_OK ||
   35.60 +        uuid_export(uuid, UUID_FMT_STR, out, NULL) != UUID_RC_OK)
   35.61 +    {
   35.62 +        memset(out, 0, sizeof(uuid_string_t));
   35.63 +    }
   35.64 +    else 
   35.65 +    {
   35.66 +        out[sizeof(uuid_string_t) - 1] = 0;
   35.67 +    }
   35.68 +
   35.69 +    if (rc_create == UUID_RC_OK)
   35.70 +    {
   35.71 +        uuid_destroy(uuid);
   35.72 +    }
   35.73 +}
   35.74 +
   35.75  #endif
   35.76  
   35.77  #if !defined(BSD) && !defined(__APPLE__)
    36.1 --- a/src/platform_unix.h	Mon Oct 03 14:34:58 2016 +0200
    36.2 +++ b/src/platform_unix.h	Wed Oct 05 15:38:42 2016 +0200
    36.3 @@ -7,6 +7,11 @@
    36.4  #include <sys/select.h>
    36.5  #include <regex.h>
    36.6  
    36.7 +#ifndef ANDROID
    36.8 +#include <uuid/uuid.h>
    36.9 +#endif
   36.10 +
   36.11 +
   36.12  #ifdef __cplusplus
   36.13  extern "C" {
   36.14  #endif
   36.15 @@ -55,6 +60,24 @@
   36.16  
   36.17  #endif
   36.18  
   36.19 +#ifndef _UUID_STRING_T
   36.20 +#define _UUID_STRING_T
   36.21 +typedef char uuid_string_t[37];
   36.22 +#endif
   36.23 +#ifdef UUID
   36.24 +#undef UUID
   36.25 +#endif
   36.26 +// on *nix, uuid_t is an array and already implements pointer semantics
   36.27 +#define UUID uuid_t
   36.28 +
   36.29 +#ifdef ANDROID
   36.30 +typedef char pEpUUID[16];
   36.31 +void uuid_generate_random(pEpUUID out);
   36.32 +void uuid_unparse_upper(pEpUUID uu, uuid_string_t out);
   36.33 +#else
   36.34 +typedef uuid_t pEpUUID;
   36.35 +#endif
   36.36 +
   36.37  #ifdef __cplusplus
   36.38  }
   36.39  #endif
    37.1 --- a/src/platform_windows.cpp	Mon Oct 03 14:34:58 2016 +0200
    37.2 +++ b/src/platform_windows.cpp	Wed Oct 05 15:38:42 2016 +0200
    37.3 @@ -267,4 +267,36 @@
    37.4      return _open(pathname, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
    37.5  }
    37.6  
    37.7 +void uuid_generate_random(pEpUUID out)
    37.8 +{
    37.9 +    RPC_STATUS rpc_status = UuidCreate(out);
   37.10 +    assert(rpc_status == RPC_S_OK);
   37.11 +}
   37.12 +
   37.13 +int uuid_parse(char *in, pEpUUID uu)
   37.14 +{
   37.15 +    unsigned char *_in = (unsigned char *) in;
   37.16 +    RPC_STATUS rpc_status = UuidFromStringA(_in, uu);
   37.17 +    assert(rpc_status == RPC_S_OK);
   37.18 +    if (rpc_status == RPC_S_INVALID_STRING_UUID)
   37.19 +        return -1;
   37.20 +    return 0;
   37.21 +}
   37.22 +
   37.23 +void uuid_unparse_upper(pEpUUID uu, uuid_string_t out)
   37.24 +{
   37.25 +    unsigned char *_out = (unsigned char*)out;
   37.26 +    RPC_CSTR str;
   37.27 +    RPC_STATUS rpc_status = UuidToStringA(uu, &str);
   37.28 +    assert(rpc_status == RPC_S_OK);
   37.29 +    if (rpc_status == RPC_S_OK) {
   37.30 +        memcpy(out, str, 36);
   37.31 +        out[36] = 0;
   37.32 +        RpcStringFreeA(&str);
   37.33 +    }
   37.34 +    else { // if (rpc_status == RPC_S_OUT_OF_MEMORY)
   37.35 +        memset(out, 0, 37);
   37.36 +    }
   37.37 +}
   37.38 +
   37.39  } // "C"
    38.1 --- a/src/platform_windows.h	Mon Oct 03 14:34:58 2016 +0200
    38.2 +++ b/src/platform_windows.h	Wed Oct 05 15:38:42 2016 +0200
    38.3 @@ -4,6 +4,15 @@
    38.4  
    38.5  #pragma warning(disable : 4996)
    38.6  
    38.7 +// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
    38.8 +// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
    38.9 +// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
   38.10 +// Including winsock2.h here fixes the problem for now...
   38.11 +#ifdef WIN32 
   38.12 +#include <winsock2.h>
   38.13 +#endif // WIN32 
   38.14 +
   38.15 +#include <Rpc.h>
   38.16  #include <string.h>
   38.17  #include <io.h>
   38.18  #include <basetsd.h>
   38.19 @@ -60,6 +69,15 @@
   38.20  
   38.21  long random(void);
   38.22  
   38.23 +// on Windoze, uuid_t needs pointer semantics
   38.24 +typedef UUID pEpUUID[1];
   38.25 +#define _UUID_STRING_T
   38.26 +typedef char uuid_string_t[37];
   38.27 +
   38.28 +void uuid_generate_random(pEpUUID out);
   38.29 +int uuid_parse(char *in, pEpUUID uu);
   38.30 +void uuid_unparse_upper(pEpUUID uu, uuid_string_t out);
   38.31 +
   38.32  #ifndef inline
   38.33  #define inline __inline
   38.34  #endif
    39.1 --- a/src/sync.c	Mon Oct 03 14:34:58 2016 +0200
    39.2 +++ b/src/sync.c	Wed Oct 05 15:38:42 2016 +0200
    39.3 @@ -3,29 +3,102 @@
    39.4  #include <memory.h>
    39.5  #include <assert.h>
    39.6  
    39.7 +#include "asn1_helper.h"
    39.8 +#include "../asn.1/DeviceGroup-Protocol.h"
    39.9 +
   39.10 +// receive_sync_msg is defined in the sync_actions
   39.11 +
   39.12 +PEP_STATUS receive_sync_msg(
   39.13 +        PEP_SESSION session,
   39.14 +        sync_msg_t *sync_msg
   39.15 +    );
   39.16  
   39.17  DYNAMIC_API PEP_STATUS register_sync_callbacks(
   39.18          PEP_SESSION session,
   39.19          void *obj,
   39.20          messageToSend_t messageToSend,
   39.21 -        showHandshake_t showHandshake
   39.22 +        showHandshake_t showHandshake,
   39.23 +        inject_sync_msg_t inject_sync_msg,
   39.24 +        retrieve_next_sync_msg_t retrieve_next_sync_msg
   39.25      )
   39.26  {
   39.27 +    assert(session && obj && messageToSend && showHandshake && inject_sync_msg && retrieve_next_sync_msg);
   39.28 +    if (!(session && obj && messageToSend && showHandshake && inject_sync_msg && retrieve_next_sync_msg))
   39.29 +        return PEP_ILLEGAL_VALUE;
   39.30 +
   39.31 +    unsigned char uuid[16];
   39.32 +    uuid_generate_random(uuid);
   39.33 +    uuid_unparse_upper(uuid, session->sync_uuid);
   39.34 +
   39.35      session->sync_obj = obj;
   39.36      session->messageToSend = messageToSend;
   39.37      session->showHandshake = showHandshake;
   39.38 +    session->inject_sync_msg = inject_sync_msg;
   39.39 +    session->retrieve_next_sync_msg = retrieve_next_sync_msg;
   39.40 +
   39.41 +    // start state machine
   39.42 +    session->sync_state = InitState;
   39.43 +    PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL);
   39.44 +    if (status != PEP_STATUS_OK)
   39.45 +        unregister_sync_callbacks(session);
   39.46 +
   39.47 +    return status;
   39.48 +}
   39.49 +
   39.50 +DYNAMIC_API PEP_STATUS attach_sync_session(
   39.51 +        PEP_SESSION session,
   39.52 +        PEP_SESSION sync_session
   39.53 +    )
   39.54 +{
   39.55 +    assert(session && sync_session && sync_session->sync_obj && sync_session->inject_sync_msg );
   39.56 +    if (!(session && sync_session && sync_session->sync_obj && sync_session->inject_sync_msg ))
   39.57 +        return PEP_ILLEGAL_VALUE;
   39.58 +
   39.59 +    memcpy(session->sync_uuid, sync_session->sync_uuid, 37);
   39.60 +
   39.61 +    session->sync_obj = sync_session->sync_obj;
   39.62 +    session->inject_sync_msg = sync_session->inject_sync_msg;
   39.63  
   39.64      return PEP_STATUS_OK;
   39.65  }
   39.66  
   39.67 +DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session)
   39.68 +{
   39.69 +    assert(session && session->sync_obj && session->inject_sync_msg );
   39.70 +    if (!(session && session->sync_obj && session->inject_sync_msg ))
   39.71 +        return PEP_ILLEGAL_VALUE;
   39.72 +
   39.73 +    memset(session->sync_uuid, 0, 37);
   39.74 +
   39.75 +    session->sync_obj = NULL;
   39.76 +    session->inject_sync_msg = NULL;
   39.77 +
   39.78 +    return PEP_STATUS_OK;
   39.79 +}
   39.80 +
   39.81 +int call_inject_sync_msg(PEP_SESSION session, void *msg)
   39.82 +{
   39.83 +    if(session->inject_sync_msg && session->sync_obj)
   39.84 +        return session->inject_sync_msg(msg, session->sync_obj);
   39.85 +    else
   39.86 +       return PEP_SYNC_NO_INJECT_CALLBACK;
   39.87 +}
   39.88 +
   39.89  DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
   39.90 +    // stop state machine
   39.91 +    session->sync_state = DeviceState_state_NONE;
   39.92 +
   39.93 +    // unregister
   39.94      session->sync_obj = NULL;
   39.95      session->messageToSend = NULL;
   39.96      session->showHandshake = NULL;
   39.97 +    session->inject_sync_msg = NULL;
   39.98 +    session->retrieve_next_sync_msg = NULL;
   39.99  }
  39.100  
  39.101  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
  39.102          PEP_SESSION session,
  39.103 +        Identity partner,
  39.104          sync_handshake_result result
  39.105      )
  39.106  {
  39.107 @@ -33,20 +106,134 @@
  39.108      if (!session)
  39.109          return PEP_ILLEGAL_VALUE;
  39.110  
  39.111 +    PEP_STATUS status = PEP_STATUS_OK;
  39.112 +
  39.113      switch (result) {
  39.114          case SYNC_HANDSHAKE_CANCEL:
  39.115 -            fsm_DeviceState_inject(session, Cancel, NULL, 0);
  39.116 +            status = fsm_DeviceState_inject(session, Cancel, NULL, 0);
  39.117              break;
  39.118          case SYNC_HANDSHAKE_ACCEPTED:
  39.119 -            fsm_DeviceState_inject(session, HandshakeAccepted, NULL, 0);
  39.120 +            status = fsm_DeviceState_inject(session, HandshakeAccepted, partner, 0);
  39.121              break;
  39.122          case SYNC_HANDSHAKE_REJECTED:
  39.123 -            fsm_DeviceState_inject(session, HandshakeRejected, NULL, 0);
  39.124 +            status = fsm_DeviceState_inject(session, HandshakeRejected, partner, 0);
  39.125              break;
  39.126          default:
  39.127              return PEP_ILLEGAL_VALUE;
  39.128      }
  39.129  
  39.130 +    return status;
  39.131 +}
  39.132 +
  39.133 +DYNAMIC_API PEP_STATUS do_sync_protocol(
  39.134 +        PEP_SESSION session,
  39.135 +        void *management
  39.136 +    )
  39.137 +{
  39.138 +    sync_msg_t *msg = NULL;
  39.139 +    PEP_STATUS status = PEP_STATUS_OK;
  39.140 +
  39.141 +    assert(session && session->retrieve_next_sync_msg);
  39.142 +    assert(management);
  39.143 +
  39.144 +    if (!(session && session->retrieve_next_sync_msg) || !management)
  39.145 +        return PEP_ILLEGAL_VALUE;
  39.146 +
  39.147 +    log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
  39.148 +
  39.149 +    while ((msg = (sync_msg_t *) session->retrieve_next_sync_msg(management))) 
  39.150 +    {
  39.151 +        if ((status = receive_sync_msg(session, msg) != PEP_STATUS_OK)) {
  39.152 +            char buffer[MAX_LINELENGTH];
  39.153 +            memset(buffer, 0, MAX_LINELENGTH);
  39.154 +            snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
  39.155 +            log_event(session, buffer, "pEp sync protocol", NULL, NULL);
  39.156 +        }
  39.157 +    }
  39.158 +
  39.159 +    log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
  39.160 +
  39.161      return PEP_STATUS_OK;
  39.162  }
  39.163  
  39.164 +DYNAMIC_API PEP_STATUS decode_sync_msg(
  39.165 +        const char *data,
  39.166 +        size_t size,
  39.167 +        char **text
  39.168 +    )
  39.169 +{
  39.170 +    PEP_STATUS status = PEP_STATUS_OK;
  39.171 +
  39.172 +    assert(data && text);
  39.173 +    if (!(data && text))
  39.174 +        return PEP_ILLEGAL_VALUE;
  39.175 +
  39.176 +    *text = NULL;
  39.177 +
  39.178 +    DeviceGroup_Protocol_t *msg = NULL;
  39.179 +    uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
  39.180 +            data, size);
  39.181 +    if (!msg)
  39.182 +        return PEP_SYNC_ILLEGAL_MESSAGE;
  39.183 +
  39.184 +    growing_buf_t *dst = new_growing_buf();
  39.185 +    if (!dst) {
  39.186 +        status = PEP_OUT_OF_MEMORY;
  39.187 +        goto the_end;
  39.188 +    }
  39.189 +
  39.190 +    asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
  39.191 +            XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
  39.192 +    if (er.encoded == -1) {
  39.193 +        status = PEP_CANNOT_ENCODE;
  39.194 +        goto the_end;
  39.195 +    }
  39.196 +
  39.197 +    *text = dst->data;
  39.198 +    dst->data = NULL;
  39.199 +
  39.200 +the_end:
  39.201 +    free_growing_buf(dst);
  39.202 +    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  39.203 +    return status;
  39.204 +}
  39.205 +
  39.206 +DYNAMIC_API PEP_STATUS encode_sync_msg(
  39.207 +        const char *text,
  39.208 +        char **data,
  39.209 +        size_t *size
  39.210 +    )
  39.211 +{
  39.212 +    PEP_STATUS status = PEP_STATUS_OK;
  39.213 +
  39.214 +    assert(text && data && size);
  39.215 +    if (!(text && data && size))
  39.216 +        return PEP_ILLEGAL_VALUE;
  39.217 +
  39.218 +    *data = NULL;
  39.219 +    *size = 0;
  39.220 +
  39.221 +    DeviceGroup_Protocol_t *msg = NULL;
  39.222 +    asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
  39.223 +            (void **) &msg, (const void *) text, strlen(text));
  39.224 +    if (dr.code != RC_OK) {
  39.225 +        status = PEP_SYNC_ILLEGAL_MESSAGE;
  39.226 +        goto the_end;
  39.227 +    }
  39.228 +
  39.229 +    char *payload = NULL;
  39.230 +    ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
  39.231 +            NULL, msg, (void **) &payload);
  39.232 +    if (_size == -1) {
  39.233 +        status = PEP_CANNOT_ENCODE;
  39.234 +        goto the_end;
  39.235 +    }
  39.236 +
  39.237 +    *data = payload;
  39.238 +    *size = (size_t) _size;
  39.239 +
  39.240 +the_end:
  39.241 +    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  39.242 +    return status;
  39.243 +}
  39.244 +
    40.1 --- a/src/sync.h	Mon Oct 03 14:34:58 2016 +0200
    40.2 +++ b/src/sync.h	Wed Oct 05 15:38:42 2016 +0200
    40.3 @@ -12,7 +12,7 @@
    40.4  extern "C" {
    40.5  #endif
    40.6  
    40.7 -// messageToSend() - send a beacon message
    40.8 +// messageToSend() - send a message
    40.9  //
   40.10  //  parameters:
   40.11  //      obj (in)        object handle (implementation defined)
   40.12 @@ -20,8 +20,11 @@
   40.13  //
   40.14  //  return value:
   40.15  //      PEP_STATUS_OK or any other value on error
   40.16 +//
   40.17 +//  caveat:
   40.18 +//      the ownership of msg goes to the callee
   40.19  
   40.20 -typedef PEP_STATUS (*messageToSend_t)(void *obj, const message *msg);
   40.21 +typedef PEP_STATUS (*messageToSend_t)(void *obj, message *msg);
   40.22  
   40.23  
   40.24  typedef enum _sync_handshake_result {
   40.25 @@ -34,30 +37,59 @@
   40.26  //
   40.27  //  parameters:
   40.28  //      obj (in)        object handle (implementation defined)
   40.29 -//      self (in)       own identity
   40.30 +//      me (in)         own identity
   40.31  //      partner (in)    identity of partner
   40.32  //
   40.33  //  return value:
   40.34  //      PEP_STATUS_OK or any other value on error
   40.35 +//
   40.36 +//  caveat:
   40.37 +//      ownership of self and partner go to the callee
   40.38  
   40.39  typedef PEP_STATUS (*showHandshake_t)(
   40.40          void *obj,
   40.41 -        const pEp_identity *self,
   40.42 -        const pEp_identity *partner
   40.43 +        pEp_identity *me,
   40.44 +        pEp_identity *partner
   40.45      );
   40.46  
   40.47  
   40.48  // deliverHandshakeResult() - give the result of the handshake dialog
   40.49  //
   40.50  //  parameters:
   40.51 -//      session (in)    session handle
   40.52 -//      result (in)     handshake result
   40.53 +//      session (in)        session handle
   40.54 +//      result (in)         handshake result
   40.55  
   40.56  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
   40.57          PEP_SESSION session,
   40.58 +        Identity partner,
   40.59          sync_handshake_result result
   40.60      );
   40.61  
   40.62 +// sync_msg_t - items queued for serialized handling by protocol engine
   40.63 +typedef struct _sync_msg_t sync_msg_t;
   40.64 +
   40.65 +// inject_sync_msg - inject sync protocol message
   40.66 +//
   40.67 +//  parameters:
   40.68 +//      msg (in)            message to inject
   40.69 +//      management (in)     application defined
   40.70 +//
   40.71 +//  return value:
   40.72 +//      0 if msg could be stored successfully or nonzero otherwise
   40.73 +
   40.74 +typedef int (*inject_sync_msg_t)(void *msg, void *management);
   40.75 +
   40.76 +
   40.77 +// retrieve_next_sync_msg - receive next sync message
   40.78 +//
   40.79 +//  parameters:
   40.80 +//      management (in)     application defined
   40.81 +//
   40.82 +//  return value:
   40.83 +//      next message or NULL for termination
   40.84 +
   40.85 +typedef void *(*retrieve_next_sync_msg_t)(void *management);
   40.86 +
   40.87  
   40.88  // register_sync_callbacks() - register adapter's callbacks
   40.89  //
   40.90 @@ -66,6 +98,7 @@
   40.91  //      obj (in)                    object handle (implementation defined)
   40.92  //      messageToSend (in)          callback for sending message
   40.93  //      showHandshake (in)          callback for doing the handshake
   40.94 +//      retrieve_next_sync_msg (in) callback for receiving sync messages
   40.95  //
   40.96  //  return value:
   40.97  //      PEP_STATUS_OK or any other value on errror
   40.98 @@ -77,17 +110,101 @@
   40.99          PEP_SESSION session,
  40.100          void *obj,
  40.101          messageToSend_t messageToSend,
  40.102 -        showHandshake_t showHandshake
  40.103 +        showHandshake_t showHandshake,
  40.104 +        inject_sync_msg_t inject_sync_msg,
  40.105 +        retrieve_next_sync_msg_t retrieve_next_sync_msg
  40.106      );
  40.107  
  40.108 +// attach_sync_session() - attach session to a session running keysync state machine 
  40.109 +//
  40.110 +//  parameters:
  40.111 +//      session (in)                session to attach
  40.112 +//      sync_session (in)           session running keysync
  40.113 +//
  40.114 +//  return value:
  40.115 +//      PEP_STATUS_OK or any other value on errror
  40.116 +//
  40.117 +//  caveat:
  40.118 +//      register_sync_callbacks must have been called on sync_session
  40.119 +//      call that BEFORE you're using that session in any other part of the engine
  40.120 +
  40.121 +DYNAMIC_API PEP_STATUS attach_sync_session(
  40.122 +        PEP_SESSION session,
  40.123 +        PEP_SESSION sync_session
  40.124 +    );
  40.125 +
  40.126 +// detach_sync_session() - detach previously attached sync session
  40.127 +//
  40.128 +//  parameters:
  40.129 +//      session (in)                session to detach 
  40.130 +
  40.131 +DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session);
  40.132  
  40.133  // unregister_sync_callbacks() - unregister adapter's callbacks
  40.134  //
  40.135  //  parameters:
  40.136 -//      session (in)                session where to store obj handle
  40.137 +//      session (in)                session to unregister
  40.138  
  40.139  DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session);
  40.140  
  40.141 +// do_sync_protocol() - function to be run on an extra thread
  40.142 +//
  40.143 +//  parameters:
  40.144 +//      session                 pEp session to use
  40.145 +//      retrieve_next_sync_msg  pointer to retrieve_next_identity() callback
  40.146 +//                              which returns at least a valid address field in
  40.147 +//                              the identity struct
  40.148 +//      management              management data to give to keymanagement
  40.149 +//                              (implementation defined)
  40.150 +//
  40.151 +//  return value:
  40.152 +//      PEP_STATUS_OK if thread has to terminate successfully or any other
  40.153 +//      value on failure
  40.154 +//
  40.155 +//  caveat:
  40.156 +//      to ensure proper working of this library, a thread has to be started
  40.157 +//      with this function immediately after initialization
  40.158 +//      do_keymanagement() calls retrieve_next_identity(management)
  40.159 +
  40.160 +DYNAMIC_API PEP_STATUS do_sync_protocol(
  40.161 +        PEP_SESSION session,
  40.162 +        void *management
  40.163 +    );
  40.164 +
  40.165 +// free_sync_msg() - free sync_msg_t struct when not passed to do_sync_protocol  
  40.166 +//
  40.167 +//  parameters:
  40.168 +//      sync_msg (in)            pointer to sync_msg_t struct to free
  40.169 +
  40.170 +DYNAMIC_API void free_sync_msg(sync_msg_t *sync_msg);
  40.171 +
  40.172 +// decode_sync_msg() - decode sync message from PER into XER
  40.173 +//
  40.174 +//  parameters:
  40.175 +//      data (in)               PER encoded data
  40.176 +//      size (in)               size of PER encoded data
  40.177 +//      text (out)              XER text of the same sync message
  40.178 +
  40.179 +DYNAMIC_API PEP_STATUS decode_sync_msg(
  40.180 +        const char *data,
  40.181 +        size_t size,
  40.182 +        char **text
  40.183 +    );
  40.184 +
  40.185 +
  40.186 +// encode_sync_msg() - encode sync message from XER into PER
  40.187 +//
  40.188 +//  parameters:
  40.189 +//      text (in)               string with XER text of the sync message
  40.190 +//      data (out)              PER encoded data
  40.191 +//      size (out)              size of PER encoded data
  40.192 +
  40.193 +DYNAMIC_API PEP_STATUS encode_sync_msg(
  40.194 +        const char *text,
  40.195 +        char **data,
  40.196 +        size_t *size
  40.197 +    );
  40.198 +
  40.199  
  40.200  #ifdef __cplusplus
  40.201  }
    41.1 --- a/src/sync_actions.c	Mon Oct 03 14:34:58 2016 +0200
    41.2 +++ b/src/sync_actions.c	Wed Oct 05 15:38:42 2016 +0200
    41.3 @@ -4,7 +4,98 @@
    41.4  #include "pEp_internal.h"
    41.5  #include "message.h"
    41.6  #include "sync_fsm.h"
    41.7 +#include "map_asn1.h"
    41.8 +#include "baseprotocol.h"
    41.9  
   41.10 +// conditions
   41.11 +
   41.12 +static const char *sql_stored_group_keys =
   41.13 +        "select count(device_group) from person where id = '" PEP_OWN_USERID "';"; 
   41.14 +
   41.15 +static int _stored_group_keys(void *_gc, int count, char **text, char **name)
   41.16 +{
   41.17 +    assert(_gc);
   41.18 +    assert(count == 1);
   41.19 +    assert(text && text[0]);
   41.20 +    if (!(_gc && count == 1 && text && text[0]))
   41.21 +        return -1;
   41.22 +
   41.23 +    bool *gc = (bool *) _gc;
   41.24 +    *gc = atoi(text[0]) != 0;
   41.25 +    return 0;
   41.26 +}
   41.27 +
   41.28 +int storedGroupKeys(PEP_SESSION session)
   41.29 +{
   41.30 +    assert(session);
   41.31 +    if (!session)
   41.32 +        return invalid_condition; // error
   41.33 +
   41.34 +    bool gc = false;
   41.35 +    int int_result = sqlite3_exec(
   41.36 +        session->db,
   41.37 +        sql_stored_group_keys,
   41.38 +        _stored_group_keys,
   41.39 +        &gc,
   41.40 +        NULL
   41.41 +    );
   41.42 +    assert(int_result == SQLITE_OK);
   41.43 +    if (int_result != SQLITE_OK)
   41.44 +        return invalid_condition; // error
   41.45 +
   41.46 +    if (gc)
   41.47 +        return 1;
   41.48 +    else
   41.49 +        return 0;
   41.50 +}
   41.51 +
   41.52 +int keyElectionWon(PEP_SESSION session, Identity partner)
   41.53 +{
   41.54 +    assert(session);
   41.55 +    assert(partner);
   41.56 +    if (!(session && partner))
   41.57 +        return invalid_condition; // error
   41.58 +
   41.59 +    // an already existing group always wins
   41.60 +
   41.61 +    if (storedGroupKeys(session)) {
   41.62 +        assert(!(partner->flags & PEP_idf_devicegroup));
   41.63 +        return 1;
   41.64 +    }
   41.65 +
   41.66 +    if (partner->flags & PEP_idf_devicegroup)
   41.67 +        return 0;
   41.68 +
   41.69 +    Identity me = NULL;
   41.70 +    PEP_STATUS status = get_identity(session, partner->address, PEP_OWN_USERID,
   41.71 +            &me);
   41.72 +    if (status == PEP_OUT_OF_MEMORY)
   41.73 +        return invalid_out_of_memory;
   41.74 +    if (status != PEP_STATUS_OK)
   41.75 +        return invalid_condition; // error
   41.76 +
   41.77 +    int result = invalid_condition; // error state has to be overwritten
   41.78 +
   41.79 +    time_t own_created;
   41.80 +    time_t partners_created;
   41.81 +
   41.82 +    status = key_created(session, me->fpr, &own_created);
   41.83 +    if (status != PEP_STATUS_OK)
   41.84 +        goto the_end;
   41.85 +
   41.86 +    status = key_created(session, partner->fpr, &partners_created);
   41.87 +    if (status != PEP_STATUS_OK)
   41.88 +        goto the_end;
   41.89 +
   41.90 +    if (own_created > partners_created)
   41.91 +        result = 0;
   41.92 +    else
   41.93 +        result = 1;
   41.94 +
   41.95 +the_end:
   41.96 +    free_identity(me);
   41.97 +    return result;
   41.98 +}
   41.99  
  41.100  // showHandshake() - trigger the handshake dialog of the application
  41.101  //
  41.102 @@ -19,39 +110,49 @@
  41.103  PEP_STATUS showHandshake(
  41.104          PEP_SESSION session,
  41.105          DeviceState_state state,
  41.106 -        const Identity partner
  41.107 +        Identity partner,
  41.108 +        void *extra
  41.109      )
  41.110  {
  41.111      PEP_STATUS status = PEP_STATUS_OK;
  41.112 +
  41.113      assert(session);
  41.114      assert(partner);
  41.115 +    assert(extra == NULL);
  41.116 +
  41.117      if (!(session && partner))
  41.118          return PEP_ILLEGAL_VALUE;
  41.119 +
  41.120      assert(session->showHandshake);
  41.121      if (!session->showHandshake)
  41.122          return PEP_SYNC_NO_TRUSTWORDS_CALLBACK;
  41.123  
  41.124 +    // showHandshake take ownership of given identities
  41.125      pEp_identity *me = NULL;
  41.126      status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
  41.127      if (status != PEP_STATUS_OK)
  41.128          goto error;
  41.129      
  41.130 -    status = session->showHandshake(session, me, partner);
  41.131 +    pEp_identity *_partner = NULL;
  41.132 +    _partner = identity_dup(partner);
  41.133 +    if (_partner == NULL){
  41.134 +        status = PEP_OUT_OF_MEMORY;
  41.135 +        goto error;
  41.136 +    }
  41.137 +
  41.138 +    status = session->showHandshake(session->sync_obj, me, _partner);
  41.139      if (status != PEP_STATUS_OK)
  41.140          goto error;
  41.141  
  41.142 -    free_identity(me);
  41.143      return status;
  41.144  
  41.145 -enomem:
  41.146 -    status = PEP_OUT_OF_MEMORY;
  41.147  error:
  41.148      free_identity(me);
  41.149      return status;
  41.150  }
  41.151  
  41.152  
  41.153 -// reject() - stores rejection of partner
  41.154 +// acceptHandshake() - stores acception of partner
  41.155  //
  41.156  //  params:
  41.157  //      session (in)        session handle
  41.158 @@ -61,33 +162,28 @@
  41.159  //  returns:
  41.160  //      PEP_STATUS_OK or any other value on error
  41.161  
  41.162 -PEP_STATUS reject(
  41.163 +PEP_STATUS acceptHandshake(
  41.164          PEP_SESSION session,
  41.165          DeviceState_state state,
  41.166 -        const Identity partner
  41.167 +        Identity partner,
  41.168 +        void *extra
  41.169      )
  41.170  {
  41.171      PEP_STATUS status = PEP_STATUS_OK;
  41.172  
  41.173      assert(session);
  41.174      assert(partner);
  41.175 +    assert(extra == NULL);
  41.176      if (!(session && partner))
  41.177          return PEP_ILLEGAL_VALUE;
  41.178  
  41.179 -    // working code
  41.180 +    status = trust_personal_key(session, partner);
  41.181  
  41.182 -
  41.183 -    return status;
  41.184 -
  41.185 -enomem:
  41.186 -    status = PEP_OUT_OF_MEMORY;
  41.187 -error:
  41.188 -    // free...
  41.189      return status;
  41.190  }
  41.191  
  41.192  
  41.193 -// storeGroupKeys() - 
  41.194 +// rejectHandshake() - stores rejection of partner
  41.195  //
  41.196  //  params:
  41.197  //      session (in)        session handle
  41.198 @@ -97,28 +193,73 @@
  41.199  //  returns:
  41.200  //      PEP_STATUS_OK or any other value on error
  41.201  
  41.202 -PEP_STATUS storeGroupKeys(
  41.203 +PEP_STATUS rejectHandshake(
  41.204          PEP_SESSION session,
  41.205          DeviceState_state state,
  41.206 -        const Identity partner
  41.207 +        Identity partner,
  41.208 +        void *extra
  41.209      )
  41.210  {
  41.211      PEP_STATUS status = PEP_STATUS_OK;
  41.212  
  41.213      assert(session);
  41.214      assert(partner);
  41.215 +    assert(extra == NULL);
  41.216      if (!(session && partner))
  41.217          return PEP_ILLEGAL_VALUE;
  41.218  
  41.219 -    // working code
  41.220 +    status = set_identity_flags(session, partner,
  41.221 +            partner->flags | PEP_idf_not_for_sync);
  41.222  
  41.223 +    return status;
  41.224 +}
  41.225  
  41.226 +
  41.227 +// storeGroupKeys() - 
  41.228 +//
  41.229 +//  params:
  41.230 +//      session (in)        session handle
  41.231 +//      state (in)          state the state machine is in
  41.232 +//      partner (in)        partner to communicate with
  41.233 +//      _group_keys (in)    group keys received from partner
  41.234 +//
  41.235 +//  returns:
  41.236 +//      PEP_STATUS_OK or any other value on error
  41.237 +
  41.238 +PEP_STATUS storeGroupKeys(
  41.239 +        PEP_SESSION session,
  41.240 +        DeviceState_state state,
  41.241 +        Identity partner,
  41.242 +        void *_group_keys
  41.243 +    )
  41.244 +{
  41.245 +    PEP_STATUS status = PEP_STATUS_OK;
  41.246 +
  41.247 +    assert(session);
  41.248 +    assert(partner);
  41.249 +    assert(_group_keys);
  41.250 +    if (!(session && partner && _group_keys))
  41.251 +        return PEP_ILLEGAL_VALUE;
  41.252 +
  41.253 +    identity_list *group_keys = (identity_list *) _group_keys;
  41.254 +
  41.255 +    for (identity_list *il = group_keys; il && il->ident; il = il->next) {
  41.256 +        free(il->ident->user_id);
  41.257 +        il->ident->user_id = strdup(PEP_OWN_USERID);
  41.258 +        assert(il->ident->user_id);
  41.259 +        if (!il->ident->user_id)
  41.260 +            goto enomem;
  41.261 +        status = set_identity(session, il->ident);
  41.262 +        if (status != PEP_STATUS_OK)
  41.263 +            break;
  41.264 +    }
  41.265 +
  41.266 +    free_identity_list(group_keys);
  41.267      return status;
  41.268  
  41.269  enomem:
  41.270      status = PEP_OUT_OF_MEMORY;
  41.271 -error:
  41.272 -    // free...
  41.273 +    free_identity_list(group_keys);
  41.274      return status;
  41.275  }
  41.276  
    42.1 --- a/src/sync_driver.c	Mon Oct 03 14:34:58 2016 +0200
    42.2 +++ b/src/sync_driver.c	Wed Oct 05 15:38:42 2016 +0200
    42.3 @@ -8,14 +8,32 @@
    42.4          PEP_SESSION session,
    42.5          DeviceState_event event,
    42.6          Identity partner,
    42.7 -        DeviceState_state state_partner
    42.8 +        void *extra
    42.9      )
   42.10  {
   42.11 -    PEP_STATUS status = PEP_STATUS_OK;
   42.12 +    assert(session);
   42.13 +    if (!session)
   42.14 +        return PEP_ILLEGAL_VALUE;
   42.15  
   42.16 -    session->sync_state = fsm_DeviceState(session, session->sync_state,
   42.17 -            event, partner, state_partner);
   42.18 +    while(true)
   42.19 +    {
   42.20 +        DeviceState_state new_state = fsm_DeviceState(session,
   42.21 +            session->sync_state, event, partner, extra);
   42.22  
   42.23 -    return status;
   42.24 +        if (new_state == DeviceState_state_invalid_out_of_memory)
   42.25 +            return PEP_OUT_OF_MEMORY;
   42.26 +
   42.27 +        if (new_state < 0)
   42.28 +            return PEP_SYNC_STATEMACHINE_ERROR - new_state;
   42.29 +        
   42.30 +        if (new_state == session->sync_state)
   42.31 +            break;
   42.32 +
   42.33 +        event = Init;
   42.34 +        extra = NULL;
   42.35 +        session->sync_state = new_state;
   42.36 +    } 
   42.37 +
   42.38 +    return PEP_STATUS_OK;
   42.39  }
   42.40  
    43.1 --- a/src/sync_fsm.c	Mon Oct 03 14:34:58 2016 +0200
    43.2 +++ b/src/sync_fsm.c	Wed Oct 05 15:38:42 2016 +0200
    43.3 @@ -6,92 +6,197 @@
    43.4          PEP_SESSION session,
    43.5          DeviceState_state state,
    43.6          DeviceState_event event,
    43.7 -        const Identity partner,
    43.8 -        DeviceState_state state_partner
    43.9 +        Identity partner,
   43.10 +        void *extra
   43.11      )
   43.12  {
   43.13 +    int cond_result;
   43.14 +    PEP_STATUS status = PEP_STATUS_OK;
   43.15 +
   43.16      switch (state) {
   43.17 -    case InitState:
   43.18 -        switch (event) {
   43.19 -            case Init:
   43.20 -                return Sole;
   43.21 -        default:
   43.22 -            return (DeviceState_state) invalid_event;
   43.23 -        }
   43.24 -        break;
   43.25 -    
   43.26 -    case Sole:
   43.27 -        switch (event) {
   43.28 -            case KeyGen:
   43.29 -                sendBeacon(session, state, NULL);
   43.30 -                break;
   43.31 -            case CannotDecrypt:
   43.32 -                sendBeacon(session, state, NULL);
   43.33 -                break;
   43.34 -            case Beacon:
   43.35 -                sendHandshakeRequest(session, state, partner);
   43.36 -                break;
   43.37 -            case HandshakeRequest:
   43.38 -                sendHandshakeRequest(session, state, partner);
   43.39 -                return HandshakingSole;
   43.40 -        default:
   43.41 -            return (DeviceState_state) invalid_event;
   43.42 -        }
   43.43 -        break;
   43.44 -    
   43.45 -    case HandshakingSole:
   43.46 -        switch (event) {
   43.47 -            case Init:
   43.48 -                showHandshake(session, state, partner);
   43.49 -                break;
   43.50 -            case HandshakeRejected:
   43.51 -                reject(session, state, partner);
   43.52 -                return Sole;
   43.53 -            case HandshakeAccepted:
   43.54 -                return WaitForGroupKeys;
   43.55 -        default:
   43.56 -            return (DeviceState_state) invalid_event;
   43.57 -        }
   43.58 -        break;
   43.59 -    
   43.60 -    case WaitForGroupKeys:
   43.61 -        switch (event) {
   43.62 -            case GroupKeys:
   43.63 -                storeGroupKeys(session, state, partner);
   43.64 -                return Grouped;
   43.65 -            case Cancel:
   43.66 -                return Sole;
   43.67 -            case Reject:
   43.68 -                reject(session, state, partner);
   43.69 -                return Sole;
   43.70 -        default:
   43.71 -            return (DeviceState_state) invalid_event;
   43.72 -        }
   43.73 -        break;
   43.74 -    
   43.75 -    case Grouped:
   43.76 -        switch (event) {
   43.77 -            case KeyGen:
   43.78 -                sendGroupKeys(session, state, NULL);
   43.79 -                break;
   43.80 -            case HandshakeRequest:
   43.81 -                sendHandshakeRequest(session, state, partner);
   43.82 -                showHandshake(session, state, partner);
   43.83 -                break;
   43.84 -            case HandshakeRejected:
   43.85 -                reject(session, state, partner);
   43.86 -                break;
   43.87 -            case HandshakeAccepted:
   43.88 -                sendGroupKeys(session, state, partner);
   43.89 -                break;
   43.90 -            case Reject:
   43.91 -                reject(session, state, NULL);
   43.92 -                break;
   43.93 -        default:
   43.94 -            return (DeviceState_state) invalid_event;
   43.95 -        }
   43.96 -        break;
   43.97 -    
   43.98 +        case InitState:
   43.99 +            switch (event) {
  43.100 +                case Init:
  43.101 +                    cond_result = storedGroupKeys(session);
  43.102 +                    if (cond_result < 0)
  43.103 +                        return cond_result;
  43.104 +                    if (cond_result) {
  43.105 +                        return Grouped;
  43.106 +                    }
  43.107 +                    return Sole;
  43.108 +                default:
  43.109 +                    return (DeviceState_state) invalid_event;
  43.110 +            }
  43.111 +            break;
  43.112 +        
  43.113 +        case Sole:
  43.114 +            switch (event) {
  43.115 +                case Init: break;
  43.116 +                case KeyGen:
  43.117 +                    status = sendBeacon(session, state, NULL, NULL);
  43.118 +                    if (status == PEP_OUT_OF_MEMORY)
  43.119 +                        return (int) invalid_out_of_memory;
  43.120 +                    if (status != PEP_STATUS_OK)
  43.121 +                        return (int) invalid_action;
  43.122 +                    break;
  43.123 +                case CannotDecrypt:
  43.124 +                    status = sendBeacon(session, state, NULL, NULL);
  43.125 +                    if (status == PEP_OUT_OF_MEMORY)
  43.126 +                        return (int) invalid_out_of_memory;
  43.127 +                    if (status != PEP_STATUS_OK)
  43.128 +                        return (int) invalid_action;
  43.129 +                    break;
  43.130 +                case Beacon:
  43.131 +                    status = sendHandshakeRequest(session, state, partner, NULL);
  43.132 +                    if (status == PEP_OUT_OF_MEMORY)
  43.133 +                        return (int) invalid_out_of_memory;
  43.134 +                    if (status != PEP_STATUS_OK)
  43.135 +                        return (int) invalid_action;
  43.136 +                    break;
  43.137 +                case HandshakeRequest:
  43.138 +                    status = sendHandshakeRequest(session, state, partner, NULL);
  43.139 +                    if (status == PEP_OUT_OF_MEMORY)
  43.140 +                        return (int) invalid_out_of_memory;
  43.141 +                    if (status != PEP_STATUS_OK)
  43.142 +                        return (int) invalid_action;
  43.143 +                    return HandshakingSole;
  43.144 +                default:
  43.145 +                    return (DeviceState_state) invalid_event;
  43.146 +            }
  43.147 +            break;
  43.148 +        
  43.149 +        case HandshakingSole:
  43.150 +            switch (event) {
  43.151 +                case Init:
  43.152 +                    status = showHandshake(session, state, partner, NULL);
  43.153 +                    if (status == PEP_OUT_OF_MEMORY)
  43.154 +                        return (int) invalid_out_of_memory;
  43.155 +                    if (status != PEP_STATUS_OK)
  43.156 +                        return (int) invalid_action;
  43.157 +                    break;
  43.158 +                case HandshakeRejected:
  43.159 +                    status = rejectHandshake(session, state, partner, NULL);
  43.160 +                    if (status == PEP_OUT_OF_MEMORY)
  43.161 +                        return (int) invalid_out_of_memory;
  43.162 +                    if (status != PEP_STATUS_OK)
  43.163 +                        return (int) invalid_action;
  43.164 +                    return Sole;
  43.165 +                case HandshakeAccepted:
  43.166 +                    status = acceptHandshake(session, state, partner, NULL);
  43.167 +                    if (status == PEP_OUT_OF_MEMORY)
  43.168 +                        return (int) invalid_out_of_memory;
  43.169 +                    if (status != PEP_STATUS_OK)
  43.170 +                        return (int) invalid_action;
  43.171 +                    cond_result = keyElectionWon(session, partner);
  43.172 +                    if (cond_result < 0)
  43.173 +                        return cond_result;
  43.174 +                    if (cond_result) {
  43.175 +                        status = sendGroupKeys(session, state, partner, NULL);
  43.176 +                        if (status == PEP_OUT_OF_MEMORY)
  43.177 +                            return (int) invalid_out_of_memory;
  43.178 +                        if (status != PEP_STATUS_OK)
  43.179 +                            return (int) invalid_action;
  43.180 +                        return Grouped;
  43.181 +                    }
  43.182 +                    return WaitForGroupKeysSole;
  43.183 +                default:
  43.184 +                    return (DeviceState_state) invalid_event;
  43.185 +            }
  43.186 +            break;
  43.187 +        
  43.188 +        case WaitForGroupKeysSole:
  43.189 +            switch (event) {
  43.190 +                case Init: break;
  43.191 +                case GroupKeys:
  43.192 +                    status = storeGroupKeys(session, state, partner, extra /*keys*/);
  43.193 +                    if (status == PEP_OUT_OF_MEMORY)
  43.194 +                        return (int) invalid_out_of_memory;
  43.195 +                    if (status != PEP_STATUS_OK)
  43.196 +                        return (int) invalid_action;
  43.197 +                    return Grouped;
  43.198 +                case Cancel:
  43.199 +                    return Sole;
  43.200 +                case Reject:
  43.201 +                    status = rejectHandshake(session, state, partner, NULL);
  43.202 +                    if (status == PEP_OUT_OF_MEMORY)
  43.203 +                        return (int) invalid_out_of_memory;
  43.204 +                    if (status != PEP_STATUS_OK)
  43.205 +                        return (int) invalid_action;
  43.206 +                    return Sole;
  43.207 +                default:
  43.208 +                    return (DeviceState_state) invalid_event;
  43.209 +            }
  43.210 +            break;
  43.211 +        
  43.212 +        case Grouped:
  43.213 +            switch (event) {
  43.214 +                case Init: break;
  43.215 +                case KeyGen:
  43.216 +                    status = sendGroupKeys(session, state, NULL, NULL);
  43.217 +                    if (status == PEP_OUT_OF_MEMORY)
  43.218 +                        return (int) invalid_out_of_memory;
  43.219 +                    if (status != PEP_STATUS_OK)
  43.220 +                        return (int) invalid_action;
  43.221 +                    break;
  43.222 +                case Beacon:
  43.223 +                    status = sendHandshakeRequest(session, state, partner, NULL);
  43.224 +                    if (status == PEP_OUT_OF_MEMORY)
  43.225 +                        return (int) invalid_out_of_memory;
  43.226 +                    if (status != PEP_STATUS_OK)
  43.227 +                        return (int) invalid_action;
  43.228 +                    break;
  43.229 +                case HandshakeRequest:
  43.230 +                    status = sendHandshakeRequest(session, state, partner, NULL);
  43.231 +                    if (status == PEP_OUT_OF_MEMORY)
  43.232 +                        return (int) invalid_out_of_memory;
  43.233 +                    if (status != PEP_STATUS_OK)
  43.234 +                        return (int) invalid_action;
  43.235 +                    return HandshakingGrouped;
  43.236 +                case GroupKeys:
  43.237 +                    status = storeGroupKeys(session, state, partner, extra /*keys*/);
  43.238 +                    if (status == PEP_OUT_OF_MEMORY)
  43.239 +                        return (int) invalid_out_of_memory;
  43.240 +                    if (status != PEP_STATUS_OK)
  43.241 +                        return (int) invalid_action;
  43.242 +                    return Grouped;
  43.243 +                default:
  43.244 +                    return (DeviceState_state) invalid_event;
  43.245 +            }
  43.246 +            break;
  43.247 +        
  43.248 +        case HandshakingGrouped:
  43.249 +            switch (event) {
  43.250 +                case Init:
  43.251 +                    status = showHandshake(session, state, partner, NULL);
  43.252 +                    if (status == PEP_OUT_OF_MEMORY)
  43.253 +                        return (int) invalid_out_of_memory;
  43.254 +                    if (status != PEP_STATUS_OK)
  43.255 +                        return (int) invalid_action;
  43.256 +                    break;
  43.257 +                case HandshakeRejected:
  43.258 +                    status = rejectHandshake(session, state, partner, NULL);
  43.259 +                    if (status == PEP_OUT_OF_MEMORY)
  43.260 +                        return (int) invalid_out_of_memory;
  43.261 +                    if (status != PEP_STATUS_OK)
  43.262 +                        return (int) invalid_action;
  43.263 +                    return Grouped;
  43.264 +                case HandshakeAccepted:
  43.265 +                    status = acceptHandshake(session, state, partner, NULL);
  43.266 +                    if (status == PEP_OUT_OF_MEMORY)
  43.267 +                        return (int) invalid_out_of_memory;
  43.268 +                    if (status != PEP_STATUS_OK)
  43.269 +                        return (int) invalid_action;
  43.270 +                    status = sendGroupKeys(session, state, partner, NULL);
  43.271 +                    if (status == PEP_OUT_OF_MEMORY)
  43.272 +                        return (int) invalid_out_of_memory;
  43.273 +                    if (status != PEP_STATUS_OK)
  43.274 +                        return (int) invalid_action;
  43.275 +                    return Grouped;
  43.276 +                default:
  43.277 +                    return (DeviceState_state) invalid_event;
  43.278 +            }
  43.279 +            break;
  43.280 +        
  43.281          default:
  43.282              return (DeviceState_state) invalid_state;
  43.283      }
    44.1 --- a/src/sync_fsm.h	Mon Oct 03 14:34:58 2016 +0200
    44.2 +++ b/src/sync_fsm.h	Wed Oct 05 15:38:42 2016 +0200
    44.3 @@ -2,7 +2,7 @@
    44.4  
    44.5  // state machine for DeviceState
    44.6  
    44.7 -#include "pEpEngine.h"
    44.8 +#include "message_api.h"
    44.9  
   44.10  #ifdef __cplusplus
   44.11  extern "C" {
   44.12 @@ -11,34 +11,55 @@
   44.13  // types
   44.14  
   44.15  typedef pEp_identity * Identity;
   44.16 -typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
   44.17 +typedef stringlist_t * Stringlist;
   44.18 +typedef union _param { Identity partner; stringlist_t *keylist; } param_t;
   44.19  
   44.20  // error values
   44.21  
   44.22  typedef enum _fsm_error {
   44.23 +    // these error values are corresponding to
   44.24 +    // PEP_SYNC_STATEMACHINE_ERROR - value
   44.25      invalid_state = -2,
   44.26 -    invalid_event = -3
   44.27 +    invalid_event = -3,
   44.28 +    invalid_condition = -4,
   44.29 +    invalid_action = -5,
   44.30 +
   44.31 +    // out of memory condition
   44.32 +    invalid_out_of_memory = -128
   44.33  } fsm_error;
   44.34  
   44.35 +// conditions
   44.36 +
   44.37 +int storedGroupKeys(PEP_SESSION session);
   44.38 +int keyElectionWon(PEP_SESSION session, Identity partner);
   44.39 +
   44.40  // states
   44.41  
   44.42  typedef enum _DeviceState_state {
   44.43 -    DeviceState_state_NONE = -1,
   44.44 +    // error values also in this namespace
   44.45 +    DeviceState_state_invalid_state = (int) invalid_state,
   44.46 +    DeviceState_state_invalid_event = (int) invalid_event,
   44.47 +    DeviceState_state_invalid_condition = (int) invalid_condition,
   44.48 +    DeviceState_state_invalid_action = (int) invalid_action,
   44.49 +    DeviceState_state_invalid_out_of_memory = (int) invalid_out_of_memory,
   44.50 +
   44.51 +    DeviceState_state_NONE = 0,
   44.52      InitState, 
   44.53      Sole, 
   44.54      HandshakingSole, 
   44.55 -    WaitForGroupKeys, 
   44.56 -    Grouped
   44.57 +    WaitForGroupKeysSole, 
   44.58 +    Grouped, 
   44.59 +    HandshakingGrouped
   44.60  } DeviceState_state;
   44.61  
   44.62  // events
   44.63  
   44.64  typedef enum _DeviceState_event {
   44.65 -    DeviceState_event_NONE = -1,
   44.66 -    Beacon = 1,
   44.67 -    HandshakeRequest = 2,
   44.68 -    GroupKeys = 3,
   44.69 -    Init, 
   44.70 +    DeviceState_event_NONE = 0,
   44.71 +    Init = 1,
   44.72 +    Beacon = 2,
   44.73 +    HandshakeRequest = 3,
   44.74 +    GroupKeys = 4,
   44.75      KeyGen, 
   44.76      CannotDecrypt, 
   44.77      HandshakeRejected, 
   44.78 @@ -49,12 +70,30 @@
   44.79  
   44.80  // actions
   44.81  
   44.82 -PEP_STATUS sendBeacon(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.83 -PEP_STATUS sendHandshakeRequest(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.84 -PEP_STATUS showHandshake(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.85 -PEP_STATUS reject(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.86 -PEP_STATUS storeGroupKeys(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.87 -PEP_STATUS sendGroupKeys(PEP_SESSION session, DeviceState_state state, const Identity partner);
   44.88 +PEP_STATUS sendBeacon(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.89 +PEP_STATUS sendHandshakeRequest(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.90 +PEP_STATUS showHandshake(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.91 +PEP_STATUS rejectHandshake(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.92 +PEP_STATUS acceptHandshake(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.93 +PEP_STATUS sendGroupKeys(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.94 +PEP_STATUS storeGroupKeys(PEP_SESSION session, DeviceState_state state, Identity partner, void *extra);
   44.95 +
   44.96 +// event injector
   44.97 +
   44.98 +PEP_STATUS inject_DeviceState_event(
   44.99 +    PEP_SESSION session, 
  44.100 +    DeviceState_event event,
  44.101 +    Identity partner,
  44.102 +    void *extra);
  44.103 +
  44.104 +// message receiver
  44.105 +
  44.106 +PEP_STATUS receive_DeviceState_msg(
  44.107 +        PEP_SESSION session, 
  44.108 +        message *src, 
  44.109 +        PEP_rating rating, 
  44.110 +        stringlist_t *keylist
  44.111 +    );
  44.112  
  44.113  // state machine
  44.114  
  44.115 @@ -62,8 +101,8 @@
  44.116          PEP_SESSION session,
  44.117          DeviceState_state state,
  44.118          DeviceState_event event,
  44.119 -        const Identity partner,
  44.120 -        DeviceState_state state_partner
  44.121 +        Identity partner,
  44.122 +        void *extra
  44.123      );
  44.124  
  44.125  // driver
  44.126 @@ -72,7 +111,7 @@
  44.127          PEP_SESSION session,
  44.128          DeviceState_event event,
  44.129          Identity partner,
  44.130 -        DeviceState_state state_partner
  44.131 +        void *extra
  44.132      );
  44.133  
  44.134  #ifdef __cplusplus
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/src/sync_impl.c	Wed Oct 05 15:38:42 2016 +0200
    45.3 @@ -0,0 +1,504 @@
    45.4 +#include "../asn.1/DeviceGroup-Protocol.h"
    45.5 +#include "sync_impl.h"
    45.6 +#include "pEp_internal.h"
    45.7 +#include "keymanagement.h"
    45.8 +#include "message_api.h"
    45.9 +#include "map_asn1.h"
   45.10 +#include "baseprotocol.h"
   45.11 +
   45.12 +#define SYNC_VERSION_MAJOR 1
   45.13 +#define SYNC_VERSION_MINOR 0
   45.14 +
   45.15 +struct _sync_msg_t {
   45.16 +    bool is_a_message;
   45.17 +    union {
   45.18 +        DeviceGroup_Protocol_t *message;
   45.19 +        struct {
   45.20 +            DeviceState_event event;
   45.21 +            Identity partner;
   45.22 +            void *extra;
   45.23 +        } event;
   45.24 +    } u;
   45.25 +};
   45.26 +
   45.27 +PEP_STATUS receive_sync_msg(
   45.28 +        PEP_SESSION session,
   45.29 +        sync_msg_t *sync_msg
   45.30 +    )
   45.31 +{
   45.32 +    PEP_STATUS status;
   45.33 +    void *extra = NULL;
   45.34 +    Identity partner = NULL;
   45.35 +    DeviceState_event event = DeviceState_event_NONE;
   45.36 +    assert(session && sync_msg);
   45.37 +    if (!(session && sync_msg))
   45.38 +        return PEP_ILLEGAL_VALUE;
   45.39 +
   45.40 +    if(sync_msg->is_a_message){
   45.41 +        DeviceGroup_Protocol_t *msg = sync_msg->u.message;
   45.42 +        assert(msg && msg->payload.present != DeviceGroup_Protocol__payload_PR_NOTHING);
   45.43 +        if (!(msg && msg->payload.present != DeviceGroup_Protocol__payload_PR_NOTHING)){
   45.44 +            status = PEP_OUT_OF_MEMORY;
   45.45 +            goto error;
   45.46 +        }
   45.47 +
   45.48 +        switch (msg->payload.present) {
   45.49 +            case DeviceGroup_Protocol__payload_PR_beacon:
   45.50 +                partner = Identity_to_Struct(&msg->header.me, NULL);
   45.51 +                if (!partner){
   45.52 +                    status = PEP_OUT_OF_MEMORY;
   45.53 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   45.54 +                    goto error;
   45.55 +                }
   45.56 +                event = Beacon;
   45.57 +                break;
   45.58 +
   45.59 +            case DeviceGroup_Protocol__payload_PR_handshakeRequest:
   45.60 +                partner = Identity_to_Struct(&msg->header.me, NULL);
   45.61 +                if (!partner){
   45.62 +                    status = PEP_OUT_OF_MEMORY;
   45.63 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   45.64 +                    goto error;
   45.65 +                }
   45.66 +                event = HandshakeRequest;
   45.67 +                break;
   45.68 +
   45.69 +            case DeviceGroup_Protocol__payload_PR_groupKeys:
   45.70 +                partner = Identity_to_Struct(&msg->header.me, NULL);
   45.71 +                if (!partner){
   45.72 +                    status = PEP_OUT_OF_MEMORY;
   45.73 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   45.74 +                    goto error;
   45.75 +                }
   45.76 +                identity_list *group_keys = IdentityList_to_identity_list(
   45.77 +                        &msg->payload.choice.groupKeys.ownIdentities, NULL);
   45.78 +                if (!group_keys) {
   45.79 +                    free_identity(partner);
   45.80 +                    status = PEP_OUT_OF_MEMORY;
   45.81 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   45.82 +                    goto error;
   45.83 +                }
   45.84 +                extra = (void *) group_keys;
   45.85 +                event = GroupKeys;
   45.86 +                break;
   45.87 +
   45.88 +            default:
   45.89 +                status = PEP_SYNC_ILLEGAL_MESSAGE;
   45.90 +                ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   45.91 +                goto error;
   45.92 +        }
   45.93 +    }
   45.94 +    else{
   45.95 +        partner = sync_msg->u.event.partner;
   45.96 +        extra = sync_msg->u.event.extra;
   45.97 +        event = sync_msg->u.event.event;
   45.98 +    }
   45.99 +
  45.100 +    status = fsm_DeviceState_inject(session, event, partner, extra);
  45.101 +
  45.102 +    free_identity(partner);
  45.103 +
  45.104 +error:
  45.105 +    free(sync_msg);
  45.106 +
  45.107 +    return status;
  45.108 +}
  45.109 +
  45.110 +// TODO: DYNAMIC_API was here, but broke the windows build. 
  45.111 +// We need to check whether it belongs here or it's a bug.
  45.112 +/* DYNAMIC_API */ void free_sync_msg(sync_msg_t *sync_msg)
  45.113 +{
  45.114 +    assert(sync_msg);
  45.115 +    if (!(sync_msg))
  45.116 +        return;
  45.117 +
  45.118 +    if(sync_msg->is_a_message){
  45.119 +        DeviceGroup_Protocol_t *msg = sync_msg->u.message;
  45.120 +        assert(msg);
  45.121 +        if (!(msg))
  45.122 +            return;
  45.123 +
  45.124 +        ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.125 +    }
  45.126 +    else{
  45.127 +        Identity partner = NULL;
  45.128 +        partner = sync_msg->u.event.partner;
  45.129 +        if(partner != NULL)
  45.130 +            free_identity(partner);
  45.131 +    }
  45.132 +
  45.133 +    free(sync_msg);
  45.134 +
  45.135 +    return;
  45.136 +}
  45.137 +
  45.138 +// from sync.c
  45.139 +int call_inject_sync_msg(PEP_SESSION session, void *msg);
  45.140 +
  45.141 +PEP_STATUS inject_DeviceState_event(
  45.142 +    PEP_SESSION session, 
  45.143 +    DeviceState_event event,
  45.144 +    Identity partner,
  45.145 +    void *extra)
  45.146 +{
  45.147 +    PEP_STATUS status;
  45.148 +
  45.149 +    assert(session);
  45.150 +    if (!(session))
  45.151 +        return PEP_ILLEGAL_VALUE;
  45.152 +
  45.153 +    sync_msg_t *sync_msg = malloc(sizeof(sync_msg_t));
  45.154 +    if(sync_msg == NULL)
  45.155 +        return PEP_OUT_OF_MEMORY;
  45.156 +
  45.157 +    sync_msg->is_a_message = false;
  45.158 +    sync_msg->u.event.partner = partner;
  45.159 +    sync_msg->u.event.extra = extra;
  45.160 +    sync_msg->u.event.event = event;
  45.161 +
  45.162 +    status = call_inject_sync_msg(session, sync_msg);
  45.163 +    if (status == PEP_SYNC_NO_INJECT_CALLBACK){
  45.164 +        free(sync_msg);
  45.165 +    }
  45.166 +
  45.167 +    return status;
  45.168 +}
  45.169 +
  45.170 +PEP_STATUS receive_DeviceState_msg(
  45.171 +    PEP_SESSION session, 
  45.172 +    message *src, 
  45.173 +    PEP_rating rating, 
  45.174 +    stringlist_t *keylist)
  45.175 +{
  45.176 +    assert(session && src);
  45.177 +    if (!(session && src))
  45.178 +        return PEP_ILLEGAL_VALUE;
  45.179 +
  45.180 +    bool found = false;
  45.181 +    
  45.182 +    bloblist_t *last = NULL;
  45.183 +    for (bloblist_t *bl = src->attachments; bl && bl->value; bl = bl->next) {
  45.184 +        if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sync") == 0
  45.185 +                && bl->size) {
  45.186 +            DeviceGroup_Protocol_t *msg = NULL;
  45.187 +            uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **)
  45.188 +                    &msg, bl->value, bl->size);
  45.189 +            if (msg) {
  45.190 +
  45.191 +                int32_t value = (int32_t) msg->header.sequence;
  45.192 +                char *user_id = strndup((char *) msg->header.me.user_id->buf,
  45.193 +                        msg->header.me.user_id->size);
  45.194 +                assert(user_id);
  45.195 +                if (!user_id) {
  45.196 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.197 +                    return PEP_OUT_OF_MEMORY;
  45.198 +                }
  45.199 +
  45.200 +                switch (msg->payload.present) {
  45.201 +                    // HandshakeRequest needs encryption
  45.202 +                    case DeviceGroup_Protocol__payload_PR_handshakeRequest:
  45.203 +                        if (rating < PEP_rating_reliable ||
  45.204 +                            strncmp(session->sync_uuid,
  45.205 +                                    (const char *)msg->payload.choice.handshakeRequest.partner.user_id->buf,
  45.206 +                                    msg->payload.choice.handshakeRequest.partner.user_id->size) != 0){
  45.207 +                            ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.208 +                            free(user_id);
  45.209 +                            return PEP_MESSAGE_DISCARDED;
  45.210 +                        }
  45.211 +                        break;
  45.212 +                    // accepting GroupKeys needs encryption and trust
  45.213 +                    case DeviceGroup_Protocol__payload_PR_groupKeys:
  45.214 +                        if (!keylist || rating < PEP_rating_reliable ||
  45.215 +                            strncmp(session->sync_uuid,
  45.216 +                                    (const char *)msg->payload.choice.groupKeys.partner.user_id->buf,
  45.217 +                                    msg->payload.choice.groupKeys.partner.user_id->size) != 0){
  45.218 +                            ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.219 +                            free(user_id);
  45.220 +                            return PEP_MESSAGE_DISCARDED;
  45.221 +                        }
  45.222 +
  45.223 +                        // check trust of identity with the right user_id
  45.224 +                        pEp_identity *_from = new_identity(src->from->address, 
  45.225 +                                                           keylist->value,
  45.226 +                                                           user_id,
  45.227 +                                                           src->from->username);
  45.228 +                        if (_from == NULL){
  45.229 +                            free(user_id);
  45.230 +                            ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.231 +                            return PEP_OUT_OF_MEMORY;
  45.232 +                        }
  45.233 +                        PEP_rating this_user_id_rating = PEP_rating_undefined;
  45.234 +                        identity_rating(session, _from, &this_user_id_rating);
  45.235 +                        free_identity(_from);
  45.236 +
  45.237 +                        if (this_user_id_rating < PEP_rating_trusted ) {
  45.238 +                            ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.239 +                            free(user_id);
  45.240 +                            return PEP_MESSAGE_DISCARDED;
  45.241 +                        }
  45.242 +                        break;
  45.243 +                    default:
  45.244 +                        break;
  45.245 +                }
  45.246 +
  45.247 +
  45.248 +                PEP_STATUS status = sequence_value(session, (char *) user_id,
  45.249 +                        &value);
  45.250 +
  45.251 +                if (status == PEP_STATUS_OK) {
  45.252 +                    found = true;
  45.253 +                    sync_msg_t *sync_msg = malloc(sizeof(sync_msg_t));
  45.254 +                    if(sync_msg == NULL){
  45.255 +                        ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.256 +                        return PEP_OUT_OF_MEMORY;
  45.257 +                    }
  45.258 +                    sync_msg->is_a_message = true;
  45.259 +                    sync_msg->u.message = msg;
  45.260 +                    status = call_inject_sync_msg(session, sync_msg);
  45.261 +                    if (status != PEP_STATUS_OK){
  45.262 +                        ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.263 +                        if (status == PEP_SYNC_NO_INJECT_CALLBACK){
  45.264 +                            free(sync_msg);
  45.265 +                        }
  45.266 +                        return status;
  45.267 +                    }
  45.268 +                }
  45.269 +                else if (status == PEP_OWN_SEQUENCE) {
  45.270 +                    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.271 +                    return PEP_MESSAGE_DISCARDED;
  45.272 +                }
  45.273 +            }
  45.274 +
  45.275 +            if (!session->keep_sync_msg) {
  45.276 +                bloblist_t *blob = bl;
  45.277 +                if (last)
  45.278 +                    last->next = bl->next;
  45.279 +                else
  45.280 +                    src->attachments = bl->next;
  45.281 +
  45.282 +                blob->next = NULL;
  45.283 +                free_bloblist(blob);
  45.284 +            }
  45.285 +            else {
  45.286 +                last = bl;
  45.287 +            }
  45.288 +        }
  45.289 +        else {
  45.290 +            last = bl;
  45.291 +        }
  45.292 +    }
  45.293 +
  45.294 +    if (found && !session->keep_sync_msg) {
  45.295 +        for (stringpair_list_t *spl = src->opt_fields ; spl && spl->value ;
  45.296 +                spl = spl->next) {
  45.297 +            if (spl->value->key &&
  45.298 +                    strcasecmp(spl->value->key, "pEp-auto-consume") == 0) {
  45.299 +                if (spl->value->value &&
  45.300 +                        strcasecmp(spl->value->value, "yes") == 0)
  45.301 +                    return PEP_MESSAGE_CONSUMED;
  45.302 +            }
  45.303 +        }
  45.304 +    }
  45.305 +
  45.306 +    return PEP_STATUS_OK;
  45.307 +}
  45.308 +
  45.309 +DeviceGroup_Protocol_t *new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR type)
  45.310 +{
  45.311 +    DeviceGroup_Protocol_t *msg = (DeviceGroup_Protocol_t *)
  45.312 +            calloc(1, sizeof(DeviceGroup_Protocol_t));
  45.313 +    assert(msg);
  45.314 +    if (!msg)
  45.315 +        return NULL;
  45.316 +    msg->payload.present = type;
  45.317 +    return msg;
  45.318 +}
  45.319 +
  45.320 +void free_DeviceGroup_Protocol_msg(DeviceGroup_Protocol_t *msg)
  45.321 +{
  45.322 +    ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
  45.323 +}
  45.324 +
  45.325 +PEP_STATUS unicast_msg(
  45.326 +        PEP_SESSION session,
  45.327 +        const Identity partner,
  45.328 +        DeviceState_state state,
  45.329 +        DeviceGroup_Protocol_t *msg,
  45.330 +        bool encrypted
  45.331 +    )
  45.332 +{
  45.333 +    PEP_STATUS status = PEP_STATUS_OK;
  45.334 +    char *payload = NULL;
  45.335 +    message *_message = NULL;
  45.336 +    pEp_identity *me = NULL;
  45.337 +    pEp_identity *_me = NULL;
  45.338 +
  45.339 +    assert(session && partner && state && msg);
  45.340 +    if (!(session && partner && state && msg))
  45.341 +        return PEP_ILLEGAL_VALUE;
  45.342 +
  45.343 +    assert(session->messageToSend);
  45.344 +    if (!session->messageToSend) {
  45.345 +        status = PEP_SEND_FUNCTION_NOT_REGISTERED;
  45.346 +        goto error;
  45.347 +    }
  45.348 +
  45.349 +    msg->header.version.major = SYNC_VERSION_MAJOR;
  45.350 +    msg->header.version.minor = SYNC_VERSION_MINOR;
  45.351 +
  45.352 +    status = get_identity(session, partner->address, PEP_OWN_USERID, &me);
  45.353 +    if (status != PEP_STATUS_OK)
  45.354 +        goto error;
  45.355 +    
  45.356 +    int32_t seq = 0;
  45.357 +
  45.358 +    status = sequence_value(session, session->sync_uuid, &seq);
  45.359 +    if (status != PEP_OWN_SEQUENCE && status != PEP_STATUS_OK)
  45.360 +        goto error;
  45.361 +
  45.362 +    msg->header.sequence = (long) seq;
  45.363 +
  45.364 +    _me = identity_dup(me);
  45.365 +    if (!_me)
  45.366 +        goto enomem;
  45.367 +
  45.368 +    free(_me->user_id);
  45.369 +    _me->user_id = strndup(session->sync_uuid, 36);
  45.370 +    assert(_me->user_id);
  45.371 +    if (!_me->user_id)
  45.372 +        goto enomem;
  45.373 +
  45.374 +    if (Identity_from_Struct(_me, &msg->header.me) == NULL)
  45.375 +        goto enomem;
  45.376 +
  45.377 +    free_identity(_me);
  45.378 +    _me = NULL;
  45.379 +
  45.380 +    msg->header.state = (long) state;
  45.381 +
  45.382 +    bool devicegroup = storedGroupKeys(session);
  45.383 +    if (devicegroup)
  45.384 +        msg->header.devicegroup = 1;
  45.385 +    else
  45.386 +        msg->header.devicegroup = 0;
  45.387 +
  45.388 +    if (asn_check_constraints(&asn_DEF_DeviceGroup_Protocol, msg, NULL, NULL)) {
  45.389 +        status = PEP_CONTRAINTS_VIOLATED;
  45.390 +        goto error;
  45.391 +    }
  45.392 +
  45.393 +    ssize_t size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
  45.394 +            NULL, msg, (void **) &payload);
  45.395 +    if (size == -1) {
  45.396 +        status = PEP_CANNOT_ENCODE;
  45.397 +        goto error;
  45.398 +    }
  45.399 +
  45.400 +    status = prepare_message(me, partner, payload, size, &_message);
  45.401 +    if (status != PEP_STATUS_OK)
  45.402 +        goto error;
  45.403 +    payload = NULL;
  45.404 +    free_identity(me);
  45.405 +    me = NULL;
  45.406 +
  45.407 +    if (encrypted) {
  45.408 +        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupKeys) {
  45.409 +            PEP_rating rating = PEP_rating_undefined;
  45.410 +            status = outgoing_message_rating(session, _message, &rating);
  45.411 +            if (status != PEP_STATUS_OK)
  45.412 +                goto error;
  45.413 +            if (rating < PEP_rating_trusted) {
  45.414 +                status = PEP_SYNC_NO_TRUST;
  45.415 +                goto error;
  45.416 +            }
  45.417 +            
  45.418 +            IdentityList_t *list = &msg->payload.choice.groupKeys.ownIdentities;
  45.419 +            for (int i=0; i<list->list.count; i++) {
  45.420 +                Identity_t *ident = list->list.array[i];
  45.421 +                char *fpr = strndup((const char *)ident->fpr.buf, ident->fpr.size);
  45.422 +                assert(fpr);
  45.423 +                if (!fpr)
  45.424 +                    goto enomem;
  45.425 +                static char filename[MAX_LINELENGTH];
  45.426 +                int result = snprintf(filename, MAX_LINELENGTH, "%s-sec.asc", fpr);
  45.427 +                if (result < 0)
  45.428 +                    goto enomem;
  45.429 +                char *key = NULL;
  45.430 +                size_t size = 0;
  45.431 +                status = export_secrect_key(session, fpr, &key, &size);
  45.432 +                free(fpr);
  45.433 +                if (status != PEP_STATUS_OK)
  45.434 +                    goto error;
  45.435 +                bloblist_t *bl = bloblist_add(_message->attachments,
  45.436 +                        (char *) key, size, "application/pgp-keys", filename);
  45.437 +                if (!bl)
  45.438 +                    goto enomem;
  45.439 +                if (!_message->attachments)
  45.440 +                    _message->attachments = bl;
  45.441 +            }
  45.442 +        }
  45.443 +
  45.444 +        message *_encrypted = NULL;
  45.445 +        status = encrypt_message(session, _message, NULL, &_encrypted, PEP_enc_PEP, 0);
  45.446 +        if (status != PEP_STATUS_OK)
  45.447 +            goto error;
  45.448 +        free_message(_message);
  45.449 +        _message = _encrypted;
  45.450 +    }
  45.451 +    else {
  45.452 +        attach_own_key(session, _message);
  45.453 +    }
  45.454 +
  45.455 +    status = session->messageToSend(session->sync_obj, _message);
  45.456 +    return status;
  45.457 +
  45.458 +enomem:
  45.459 +    status = PEP_OUT_OF_MEMORY;
  45.460 +error:
  45.461 +    free_identity(_me);
  45.462 +    free(payload);
  45.463 +    free_message(_message);
  45.464 +    free_identity(me);
  45.465 +    return status;
  45.466 +}
  45.467 +
  45.468 +PEP_STATUS multicast_self_msg(
  45.469 +        PEP_SESSION session,
  45.470 +        DeviceState_state state,
  45.471 +        DeviceGroup_Protocol_t *msg,
  45.472 +        bool encrypted
  45.473 +    )
  45.474 +{
  45.475 +    PEP_STATUS status = PEP_STATUS_OK;
  45.476 +
  45.477 +    assert(session && state && msg);
  45.478 +    if (!(session && state && msg))
  45.479 +        return PEP_ILLEGAL_VALUE;
  45.480 +
  45.481 +    identity_list *own_identities = NULL;
  45.482 +    status = own_identities_retrieve(session, &own_identities);
  45.483 +    if (status != PEP_STATUS_OK)
  45.484 +        return status;
  45.485 +
  45.486 +    // FIXME: exclude previously rejected identities
  45.487 +    for (identity_list *_i = own_identities; _i && _i->ident; _i = _i->next) {
  45.488 +        pEp_identity *me = _i->ident;
  45.489 +
  45.490 +        // FIXME: no deep copy for multicast supported yet
  45.491 +        DeviceGroup_Protocol_t *_msg = malloc(sizeof(DeviceGroup_Protocol_t));
  45.492 +        assert(_msg);
  45.493 +        if (_msg == NULL)
  45.494 +            goto enomem;
  45.495 +        memcpy(_msg, msg, sizeof(DeviceGroup_Protocol_t));
  45.496 +        status = unicast_msg(session, me, state, _msg, encrypted);
  45.497 +        free_DeviceGroup_Protocol_msg(_msg);
  45.498 +    }
  45.499 +
  45.500 +    free_identity_list(own_identities);
  45.501 +    return PEP_STATUS_OK;
  45.502 +
  45.503 +enomem:
  45.504 +    free_identity_list(own_identities);
  45.505 +    return PEP_OUT_OF_MEMORY;
  45.506 +}
  45.507 +
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/src/sync_impl.h	Wed Oct 05 15:38:42 2016 +0200
    46.3 @@ -0,0 +1,51 @@
    46.4 +#pragma once
    46.5 +
    46.6 +#include "message.h"
    46.7 +#include "sync.h"
    46.8 +#include "sync_fsm.h"
    46.9 +
   46.10 +#ifdef __cplusplus
   46.11 +extern "C" {
   46.12 +#endif
   46.13 +
   46.14 +PEP_STATUS receive_sync_msg(
   46.15 +        PEP_SESSION session,
   46.16 +        sync_msg_t *sync_msg
   46.17 +    );
   46.18 +
   46.19 +PEP_STATUS inject_DeviceState_event(
   46.20 +    PEP_SESSION session, 
   46.21 +    DeviceState_event event,
   46.22 +    Identity partner,
   46.23 +    void *extra);
   46.24 +
   46.25 +PEP_STATUS receive_DeviceState_msg(
   46.26 +    PEP_SESSION session, 
   46.27 +    message *src, 
   46.28 +    PEP_rating rating, 
   46.29 +    stringlist_t *keylist);
   46.30 +
   46.31 +DeviceGroup_Protocol_t *new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR type);
   46.32 +void free_DeviceGroup_Protocol_msg(DeviceGroup_Protocol_t *msg);
   46.33 +
   46.34 +PEP_STATUS unicast_msg(
   46.35 +        PEP_SESSION session,
   46.36 +        const Identity partner,
   46.37 +        DeviceState_state state,
   46.38 +        DeviceGroup_Protocol_t *msg,
   46.39 +        bool encrypted
   46.40 +    );
   46.41 +
   46.42 +PEP_STATUS multicast_self_msg(
   46.43 +        PEP_SESSION session,
   46.44 +        DeviceState_state state,
   46.45 +        DeviceGroup_Protocol_t *msg,
   46.46 +        bool encrypted
   46.47 +    );
   46.48 +
   46.49 +bool is_double(DeviceGroup_Protocol_t *msg);
   46.50 +
   46.51 +#ifdef __cplusplus
   46.52 +}
   46.53 +#endif
   46.54 +
    47.1 --- a/src/sync_send_actions.c	Mon Oct 03 14:34:58 2016 +0200
    47.2 +++ b/src/sync_send_actions.c	Wed Oct 05 15:38:42 2016 +0200
    47.3 @@ -7,6 +7,8 @@
    47.4  #include "sync_fsm.h"
    47.5  #include "baseprotocol.h"
    47.6  #include "map_asn1.h"
    47.7 +#include "../asn.1/DeviceGroup-Protocol.h"
    47.8 +#include "sync_impl.h"
    47.9  #include "../asn.1/Beacon.h"
   47.10  #include "../asn.1/HandshakeRequest.h"
   47.11  #include "../asn.1/GroupKeys.h"
   47.12 @@ -25,80 +27,32 @@
   47.13  PEP_STATUS sendBeacon(
   47.14          PEP_SESSION session,
   47.15          DeviceState_state state,
   47.16 -        const Identity partner
   47.17 +        Identity partner,
   47.18 +        void *extra
   47.19      )
   47.20  {
   47.21 -    PEP_STATUS status = PEP_STATUS_OK;
   47.22 -    Beacon_t *msg = NULL;
   47.23 -    char *payload = NULL;
   47.24 -    message *_message = NULL;
   47.25 -    pEp_identity *me = NULL;
   47.26 -
   47.27 -    assert(session);
   47.28 -    assert(!partner);
   47.29 -    if (!(session && !partner))
   47.30 +    assert(session && state);
   47.31 +    if (!(session && state))
   47.32          return PEP_ILLEGAL_VALUE;
   47.33  
   47.34 -    assert(session->messageToSend);
   47.35 -    if (!session->messageToSend)
   47.36 -        return PEP_SEND_FUNCTION_NOT_REGISTERED;
   47.37 +    PEP_STATUS status = PEP_STATUS_OK;
   47.38  
   47.39 -    msg = (Beacon_t *) calloc(1, sizeof(Beacon_t));
   47.40 -    assert(msg);
   47.41 +    DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_beacon);
   47.42      if (!msg)
   47.43          goto enomem;
   47.44  
   47.45 -    int32_t seq;
   47.46 -    status = sequence_value(session, "DeviceGroup", &seq);
   47.47 +    bool encrypted = false;
   47.48 +    status = multicast_self_msg(session, state, msg, encrypted);
   47.49      if (status != PEP_STATUS_OK)
   47.50          goto error;
   47.51 -    msg->header.sequence = (long) seq;
   47.52  
   47.53 -    msg->state = (long) state;
   47.54 -
   47.55 -    me = new_identity(NULL, NULL, NULL, NULL);
   47.56 -    if (!me)
   47.57 -        goto enomem;
   47.58 -    status = myself(session, me);
   47.59 -    if (status != PEP_STATUS_OK)
   47.60 -        goto error;
   47.61 -    if (Identity_from_Struct(me, &msg->me) == NULL)
   47.62 -        goto enomem;
   47.63 -
   47.64 -    if (asn_check_constraints(&asn_DEF_Beacon, msg, NULL, NULL)) {
   47.65 -        status = PEP_CONTRAINTS_VIOLATED;
   47.66 -        goto error;
   47.67 -    }
   47.68 -
   47.69 -    ssize_t size = uper_encode_to_new_buffer(&asn_DEF_Beacon,
   47.70 -            NULL, msg, (void **) &payload);
   47.71 -    if (size == -1) {
   47.72 -        status = PEP_CANNOT_ENCODE;
   47.73 -        goto error;
   47.74 -    }
   47.75 -
   47.76 -    status = prepare_message(me, partner, payload, size, &_message);
   47.77 -    if (status != PEP_STATUS_OK)
   47.78 -        goto error;
   47.79 -    payload = NULL;
   47.80 -
   47.81 -    free_identity(me);
   47.82 -    me = NULL;
   47.83 -
   47.84 -    status = session->messageToSend(session->sync_obj, _message);
   47.85 -
   47.86 -    free_message(_message);
   47.87 -    ASN_STRUCT_FREE(asn_DEF_Beacon, msg);
   47.88 -
   47.89 -    return status;
   47.90 +    free_DeviceGroup_Protocol_msg(msg);
   47.91 +    return PEP_STATUS_OK;
   47.92  
   47.93  enomem:
   47.94      status = PEP_OUT_OF_MEMORY;
   47.95  error:
   47.96 -    ASN_STRUCT_FREE(asn_DEF_Beacon, msg);
   47.97 -    free(payload);
   47.98 -    free_message(_message);
   47.99 -    free_identity(me);
  47.100 +    free_DeviceGroup_Protocol_msg(msg);
  47.101      return status;
  47.102  }
  47.103  
  47.104 @@ -116,83 +70,36 @@
  47.105  PEP_STATUS sendHandshakeRequest(
  47.106          PEP_SESSION session,
  47.107          DeviceState_state state,
  47.108 -        const Identity partner
  47.109 +        Identity partner,
  47.110 +        void *extra
  47.111      )
  47.112  {
  47.113 -    PEP_STATUS status = PEP_STATUS_OK;
  47.114 -    HandshakeRequest_t *msg = NULL;
  47.115 -    char *payload = NULL;
  47.116 -    message *_message = NULL;
  47.117 -    pEp_identity *me = NULL;
  47.118 -
  47.119 -    assert(session);
  47.120 -    assert(partner);
  47.121 -    if (!(session && partner))
  47.122 +    assert(session && state);
  47.123 +    if (!(session && state))
  47.124          return PEP_ILLEGAL_VALUE;
  47.125  
  47.126 -    assert(session->messageToSend);
  47.127 -    if (!session->messageToSend)
  47.128 -        return PEP_SEND_FUNCTION_NOT_REGISTERED;
  47.129 +    PEP_STATUS status = PEP_STATUS_OK;
  47.130  
  47.131 -    msg = (HandshakeRequest_t *) calloc(1, sizeof(HandshakeRequest_t));
  47.132 -    assert(msg);
  47.133 +    DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_handshakeRequest);
  47.134      if (!msg)
  47.135          goto enomem;
  47.136  
  47.137 -    int32_t seq;
  47.138 -    status = sequence_value(session, "DeviceGroup", &seq);
  47.139 +    if (Identity_from_Struct(partner,
  47.140 +                             &msg->payload.choice.handshakeRequest.partner) == NULL)
  47.141 +        goto enomem;
  47.142 +
  47.143 +    bool encrypted = true;
  47.144 +    status = unicast_msg(session, partner, state, msg, encrypted);
  47.145      if (status != PEP_STATUS_OK)
  47.146          goto error;
  47.147 -    msg->header.sequence = (long) seq;
  47.148  
  47.149 -    msg->state = (long) state;
  47.150 -
  47.151 -    me = new_identity(NULL, NULL, NULL, NULL);
  47.152 -    if (!me)
  47.153 -        goto enomem;
  47.154 -    status = myself(session, me);
  47.155 -    if (status != PEP_STATUS_OK)
  47.156 -        goto error;
  47.157 -    if (Identity_from_Struct(me, &msg->me) == NULL)
  47.158 -        goto enomem;
  47.159 -
  47.160 -    if (Identity_from_Struct(partner, &msg->partner) == NULL)
  47.161 -        goto enomem;
  47.162 -
  47.163 -    if (asn_check_constraints(&asn_DEF_HandshakeRequest, msg, NULL, NULL)) {
  47.164 -        status = PEP_CONTRAINTS_VIOLATED;
  47.165 -        goto error;
  47.166 -    }
  47.167 -
  47.168 -    ssize_t size = uper_encode_to_new_buffer(&asn_DEF_HandshakeRequest,
  47.169 -            NULL, msg, (void **) &payload);
  47.170 -    if (size == -1) {
  47.171 -        status = PEP_CANNOT_ENCODE;
  47.172 -        goto error;
  47.173 -    }
  47.174 -
  47.175 -    status = prepare_message(me, partner, payload, size, &_message);
  47.176 -    if (status != PEP_STATUS_OK)
  47.177 -        goto error;
  47.178 -    payload = NULL;
  47.179 -
  47.180 -    free_identity(me);
  47.181 -    me = NULL;
  47.182 -
  47.183 -    status = session->messageToSend(session->sync_obj, _message);
  47.184 -
  47.185 -    free_message(_message);
  47.186 -    ASN_STRUCT_FREE(asn_DEF_HandshakeRequest, msg);
  47.187 -
  47.188 -    return status;
  47.189 +    free_DeviceGroup_Protocol_msg(msg);
  47.190 +    return PEP_STATUS_OK;
  47.191  
  47.192  enomem:
  47.193      status = PEP_OUT_OF_MEMORY;
  47.194  error:
  47.195 -    ASN_STRUCT_FREE(asn_DEF_HandshakeRequest, msg);
  47.196 -    free(payload);
  47.197 -    free_message(_message);
  47.198 -    free_identity(me);
  47.199 +    free_DeviceGroup_Protocol_msg(msg);
  47.200      return status;
  47.201  }
  47.202  
  47.203 @@ -202,7 +109,7 @@
  47.204  //  params:
  47.205  //      session (in)        session handle
  47.206  //      state (in)          state the state machine is in
  47.207 -//      partner (in)        (must be NULL)
  47.208 +//      partner (in)        partner to communicate with
  47.209  //
  47.210  //  returns:
  47.211  //      PEP_STATUS_OK or any other value on error
  47.212 @@ -210,80 +117,45 @@
  47.213  PEP_STATUS sendGroupKeys(
  47.214          PEP_SESSION session,
  47.215          DeviceState_state state,
  47.216 -        const Identity partner
  47.217 +        Identity partner,
  47.218 +        void *extra
  47.219      )
  47.220  {
  47.221 -    PEP_STATUS status = PEP_STATUS_OK;
  47.222 -    GroupKeys_t *msg = NULL;
  47.223 -    char *payload = NULL;
  47.224 -    message *_message = NULL;
  47.225 -    pEp_identity *me = NULL;
  47.226 -
  47.227 -    assert(session);
  47.228 -    assert(!partner);
  47.229 -    if (!(session && !partner))
  47.230 +    assert(session && state);
  47.231 +    if (!(session && state))
  47.232          return PEP_ILLEGAL_VALUE;
  47.233  
  47.234 -    assert(session->messageToSend);
  47.235 -    if (!session->messageToSend)
  47.236 -        return PEP_SEND_FUNCTION_NOT_REGISTERED;
  47.237 +    PEP_STATUS status = PEP_STATUS_OK;
  47.238 +    identity_list *kl = new_identity_list(NULL);
  47.239  
  47.240 -    msg = (GroupKeys_t *) calloc(1, sizeof(GroupKeys_t));
  47.241 -    assert(msg);
  47.242 +    DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_groupKeys);
  47.243      if (!msg)
  47.244          goto enomem;
  47.245  
  47.246 -    int32_t seq;
  47.247 -    status = sequence_value(session, "DeviceGroup", &seq);
  47.248 +    status = own_identities_retrieve(session, &kl);
  47.249      if (status != PEP_STATUS_OK)
  47.250          goto error;
  47.251 -    msg->header.sequence = (long) seq;
  47.252 +    if (IdentityList_from_identity_list(kl, &msg->payload.choice.groupKeys.ownIdentities) == NULL)
  47.253 +        goto enomem;
  47.254  
  47.255 -    msg->state = (long) state;
  47.256 +    if (Identity_from_Struct(partner,
  47.257 +                             &msg->payload.choice.groupKeys.partner) == NULL)
  47.258 +        goto enomem;
  47.259  
  47.260 -    me = new_identity(NULL, NULL, NULL, NULL);
  47.261 -    if (!me)
  47.262 -        goto enomem;
  47.263 -    status = myself(session, me);
  47.264 +    bool encrypted = true;
  47.265 +    status = unicast_msg(session, partner, state, msg, encrypted);
  47.266      if (status != PEP_STATUS_OK)
  47.267          goto error;
  47.268 -    if (Identity_from_Struct(me, &msg->me) == NULL)
  47.269 -        goto enomem;
  47.270  
  47.271 -    if (asn_check_constraints(&asn_DEF_GroupKeys, msg, NULL, NULL)) {
  47.272 -        status = PEP_CONTRAINTS_VIOLATED;
  47.273 -        goto error;
  47.274 -    }
  47.275 -
  47.276 -    ssize_t size = uper_encode_to_new_buffer(&asn_DEF_GroupKeys,
  47.277 -            NULL, msg, (void **) &payload);
  47.278 -    if (size == -1) {
  47.279 -        status = PEP_CANNOT_ENCODE;
  47.280 -        goto error;
  47.281 -    }
  47.282 -
  47.283 -    status = prepare_message(me, partner, payload, size, &_message);
  47.284 -    if (status != PEP_STATUS_OK)
  47.285 -        goto error;
  47.286 -    payload = NULL;
  47.287 -
  47.288 -    free_identity(me);
  47.289 -    me = NULL;
  47.290 -
  47.291 -    status = session->messageToSend(session->sync_obj, _message);
  47.292 -
  47.293 -    free_message(_message);
  47.294 -    ASN_STRUCT_FREE(asn_DEF_GroupKeys, msg);
  47.295 -
  47.296 -    return status;
  47.297 +    free_identity_list(kl);
  47.298 +    free_DeviceGroup_Protocol_msg(msg);
  47.299 +    return PEP_STATUS_OK;
  47.300  
  47.301  enomem:
  47.302      status = PEP_OUT_OF_MEMORY;
  47.303  error:
  47.304 -    ASN_STRUCT_FREE(asn_DEF_GroupKeys, msg);
  47.305 -    free(payload);
  47.306 -    free_message(_message);
  47.307 -    free_identity(me);
  47.308 +    free_DeviceGroup_Protocol_msg(msg);
  47.309 +    free_identity_list(kl);
  47.310      return status;
  47.311  }
  47.312  
    48.1 --- a/sync/devicegroup.fsm	Mon Oct 03 14:34:58 2016 +0200
    48.2 +++ b/sync/devicegroup.fsm	Wed Oct 05 15:38:42 2016 +0200
    48.3 @@ -9,17 +9,23 @@
    48.4  protocol DeviceGroup {
    48.5      // all messages have a timestamp, time out and are removed after timeout
    48.6  
    48.7 +    broadcast sendBeacon;
    48.8 +    unencrypted sendBeacon;
    48.9 +
   48.10      fsm DeviceState filename=sync {
   48.11 +        condition storedGroupKeys();
   48.12 +        condition keyElectionWon(Identity partner);
   48.13 +
   48.14          state InitState {
   48.15              on Init {
   48.16 -                if (storedGroupKeys)
   48.17 +                if storedGroupKeys()
   48.18                      go Grouped;
   48.19                  go Sole;
   48.20              }
   48.21          }
   48.22  
   48.23          state Sole {
   48.24 -            on KeyGen
   48.25 +            on KeyGen // injected by generate_keypair()
   48.26                  do sendBeacon;
   48.27              on CannotDecrypt
   48.28                  do sendBeacon;  // cry, baby
   48.29 @@ -36,28 +42,29 @@
   48.30              on Init
   48.31                  do showHandshake(partner);
   48.32              on HandshakeRejected(Identity partner) {
   48.33 -                do reject(partner);             // stores rejection of partner
   48.34 +                do rejectHandshake(partner);             // stores rejection of partner
   48.35                  go Sole;
   48.36              }
   48.37              on HandshakeAccepted(Identity partner) {
   48.38 +                do acceptHandshake(partner); 
   48.39                  if keyElectionWon(partner) {    // an already existing group
   48.40                                                  // always wins
   48.41 -                    ownGroupKeys;
   48.42 -                    sendGroupKeys(partner);
   48.43 +                    do sendGroupKeys(partner);
   48.44                      go Grouped;
   48.45                  }
   48.46 -                go WaitForGroupKeys(Identity partner);
   48.47 +                go WaitForGroupKeysSole(Identity partner);
   48.48              }
   48.49          }
   48.50      
   48.51 -        state WaitForGroupKeys(Identity partner) {
   48.52 +        state WaitForGroupKeysSole(Identity partner) {
   48.53              on GroupKeys(Identity partner, Stringlist keys) {
   48.54                  do storeGroupKeys(partner, keys);
   48.55 +                // TODO : add a callback to signal finished waiting for group keys
   48.56                  go Grouped;
   48.57              }
   48.58              on Cancel go Sole;
   48.59              on Reject(Identity partner) {
   48.60 -                do reject(partner);
   48.61 +                do rejectHandshake(partner);
   48.62                  go Sole;
   48.63              }
   48.64          }
   48.65 @@ -65,22 +72,40 @@
   48.66          state Grouped {
   48.67              on KeyGen
   48.68                  do sendGroupKeys; // always send all keys
   48.69 +            on Beacon(Identity partner)
   48.70 +                do sendHandshakeRequest(partner);
   48.71              on HandshakeRequest(Identity partner) {
   48.72                  do sendHandshakeRequest(partner);
   48.73 -                do showHandshake(partner);
   48.74 +                go HandshakingGrouped(partner);
   48.75              }
   48.76 -            on HandshakeRejected(Identity partner)
   48.77 -                do reject(partner);
   48.78 -            on HandshakeAccepted(Identity partner)
   48.79 -                do sendGroupKeys(partner);
   48.80 -            on Reject(Identity partner)
   48.81 -                do reject partner;
   48.82 +            on GroupKeys(Identity partner, Stringlist keys) {
   48.83 +                do storeGroupKeys(partner, keys);
   48.84 +                // TODO : add a callback to signal finished waiting for group keys
   48.85 +                go Grouped;
   48.86 +            }
   48.87          }
   48.88  
   48.89 -        tag InitState 0;
   48.90 -        tag Beacon 1;
   48.91 -        tag HandshakeRequest 2;
   48.92 -        tag GroupKeys 3;
   48.93 +        state HandshakingGrouped(Identity partner) {
   48.94 +            on Init
   48.95 +                do showHandshake(partner);
   48.96 +            on HandshakeRejected(Identity partner) {
   48.97 +                do rejectHandshake(partner);             // stores rejection of partner
   48.98 +                go Grouped;
   48.99 +            }
  48.100 +            on HandshakeAccepted(Identity partner) {
  48.101 +                do acceptHandshake(partner); 
  48.102 +
  48.103 +                // an already existing group always wins
  48.104 +                do sendGroupKeys(partner);
  48.105 +                go Grouped;
  48.106 +            }
  48.107 +        }
  48.108 +    
  48.109 +
  48.110 +        tag Init 1;
  48.111 +        tag Beacon 2;
  48.112 +        tag HandshakeRequest 3;
  48.113 +        tag GroupKeys 4;
  48.114      }
  48.115  }
  48.116  
    49.1 --- a/sync/fsm.yml2	Mon Oct 03 14:34:58 2016 +0200
    49.2 +++ b/sync/fsm.yml2	Wed Oct 05 15:38:42 2016 +0200
    49.3 @@ -10,6 +10,6 @@
    49.4  decl event @name, on is event;
    49.5  decl transition @target, go is transition;
    49.6  decl action @name, do is action;
    49.7 -decl condition @flag, if is condition;
    49.8 +decl condition @name, if is condition;
    49.9  decl interface @name;
   49.10  decl tag @name (id);
    50.1 --- a/sync/gen_actions_skeleton.ysl2	Mon Oct 03 14:34:58 2016 +0200
    50.2 +++ b/sync/gen_actions_skeleton.ysl2	Wed Oct 05 15:38:42 2016 +0200
    50.3 @@ -7,6 +7,7 @@
    50.4  include yslt.yml2
    50.5  
    50.6  tstylesheet {
    50.7 +    include standardlib.ysl2
    50.8      include ./functions.ysl2
    50.9  
   50.10      template "/protocol" {
   50.11 @@ -27,6 +28,8 @@
   50.12          #include "«@filename»_fsm.h"
   50.13          #include "baseprotocol.h"
   50.14          #include "map_asn1.h"
   50.15 +        #include "../asn.1/DeviceGroup-Protocol.h"
   50.16 +        #include "sync_impl.h"
   50.17          ||
   50.18          for "func:distinctName(//action)"
   50.19              if "substring(@name, 1, 4) = 'send'"
   50.20 @@ -51,6 +54,7 @@
   50.21          #include "keymanagement.h"
   50.22          #include "message.h"
   50.23          #include "«@filename»_fsm.h"
   50.24 +        #include "../asn.1/DeviceGroup-Protocol.h"
   50.25  
   50.26          ||
   50.27          for "func:distinctName(//action)"
   50.28 @@ -101,7 +105,8 @@
   50.29          PEP_STATUS «$action/@name»(
   50.30                  PEP_SESSION session,
   50.31                  «$fsm»_state state,
   50.32 -                const Identity partner
   50.33 +                Identity partner,
   50.34 +                void *extra
   50.35              )
   50.36          {
   50.37              PEP_STATUS status = PEP_STATUS_OK;
   50.38 @@ -110,13 +115,13 @@
   50.39  
   50.40              // working code
   50.41  
   50.42 -
   50.43 +            // free extra
   50.44              return status;
   50.45  
   50.46          enomem:
   50.47              status = PEP_OUT_OF_MEMORY;
   50.48          error:
   50.49 -            // free...
   50.50 +            // free extra
   50.51              return status;
   50.52          }
   50.53  
   50.54 @@ -128,6 +133,7 @@
   50.55          param "fsm";
   50.56          param "filename", "'###'";
   50.57          const "name", "substring($action/@name, 5, 255)";
   50.58 +        const "lname", "concat(yml:lcase(substring($name, 1, 1)), substring($name, 2))";
   50.59  
   50.60          ||
   50.61  
   50.62 @@ -145,88 +151,67 @@
   50.63          PEP_STATUS «$action/@name»(
   50.64                  PEP_SESSION session,
   50.65                  «$fsm»_state state,
   50.66 -                const Identity partner
   50.67 +                Identity partner,
   50.68 +                void *extra
   50.69              )
   50.70          {
   50.71 +            assert(session && state);
   50.72 +            if (!(session && state))
   50.73 +                return PEP_ILLEGAL_VALUE;
   50.74 +
   50.75              PEP_STATUS status = PEP_STATUS_OK;
   50.76 -            «$name»_t *msg = NULL;
   50.77 -            char *payload = NULL;
   50.78 -            message *_message = NULL;
   50.79 -            pEp_identity *me = NULL;
   50.80 +            `` if "$name='GroupKeys'" |> identity_list *kl = new_identity_list(NULL);
   50.81  
   50.82 -            `` call "paramcheck" with "partner", "parm/partner";
   50.83 -
   50.84 -            assert(session->messageToSend);
   50.85 -            if (!session->messageToSend)
   50.86 -                return PEP_SEND_FUNCTION_NOT_REGISTERED;
   50.87 -
   50.88 -            msg = («$name»_t *) calloc(1, sizeof(«$name»_t));
   50.89 -            assert(msg);
   50.90 +            DeviceGroup_Protocol_t *msg = new_DeviceGroup_Protocol_msg(DeviceGroup_Protocol__payload_PR_«$lname»);
   50.91              if (!msg)
   50.92                  goto enomem;
   50.93 +        ||
   50.94 +        choose {
   50.95 +            when "$name='GroupKeys'" {
   50.96 +                |
   50.97 +                |> status = own_identities_retrieve(session, &kl);
   50.98 +                |> if (status != PEP_STATUS_OK)
   50.99 +                |>> goto error;
  50.100 +                |> if (IdentityList_from_identity_list(kl, &msg->payload.choice.groupKeys.ownIdentities) == NULL)
  50.101 +                |>> goto enomem;
  50.102 +            }
  50.103 +        }
  50.104 +        choose {
  50.105 +            when "$name='GroupKeys' or $name='HandshakeRequest'" {
  50.106 +                |
  50.107 +                |> if (Identity_from_Struct(partner,
  50.108 +                |>                          &msg->payload.choice.«$lname».partner) == NULL)
  50.109 +                |>> goto enomem;
  50.110 +            }
  50.111 +        }
  50.112 +        ||
  50.113  
  50.114 -            int32_t seq;
  50.115 -            status = sequence_value(session, "DeviceGroup", &seq);
  50.116 +        ||
  50.117 +        choose {
  50.118 +            when "count(/protocol/unencrypted/*[name()=$action/@name]) = 0"
  50.119 +                |> bool encrypted = true;
  50.120 +            otherwise
  50.121 +                |> bool encrypted = false;
  50.122 +        }
  50.123 +        choose {
  50.124 +            when "count(/protocol/broadcast/*[name()=$action/@name]) = 0"
  50.125 +                |> status = unicast_msg(session, partner, state, msg, encrypted);
  50.126 +            otherwise
  50.127 +                |> status = multicast_self_msg(session, state, msg, encrypted);
  50.128 +        }
  50.129 +        ||
  50.130              if (status != PEP_STATUS_OK)
  50.131                  goto error;
  50.132 -            msg->header.sequence = (long) seq;
  50.133  
  50.134 -            msg->state = (long) state;
  50.135 -
  50.136 -            me = new_identity(NULL, NULL, NULL, NULL);
  50.137 -            if (!me)
  50.138 -                goto enomem;
  50.139 -            status = myself(session, me);
  50.140 -            if (status != PEP_STATUS_OK)
  50.141 -                goto error;
  50.142 -            if (Identity_from_Struct(me, &msg->me) == NULL)
  50.143 -                goto enomem;
  50.144 -        ||
  50.145 -        if "parm or $name='OwnKeys'" |
  50.146 -        if "parm/partner"   |> if (Identity_from_Struct(partner, &msg->partner) == NULL)
  50.147 -        if "parm/partner"   |>> goto enomem;
  50.148 -        if "$name='OwnKeys'"|> stringlist_t *sl;
  50.149 -        if "$name='OwnKeys'"|> status = own_key_retrieve(session, &sl);
  50.150 -        if "$name='OwnKeys'"|> if (status != PEP_STATUS_OK)
  50.151 -        if "$name='OwnKeys'"|>> goto error;
  50.152 -        if "$name='OwnKeys'"|> if (KeyList_from_stringlist(sl, &msg->keylist) == NULL)
  50.153 -        if "$name='OwnKeys'"|>> goto enomem;
  50.154 -        ||
  50.155 -
  50.156 -            if (asn_check_constraints(&asn_DEF_«$name», msg, NULL, NULL)) {
  50.157 -                status = PEP_CONTRAINTS_VIOLATED;
  50.158 -                goto error;
  50.159 -            }
  50.160 -
  50.161 -            ssize_t size = uper_encode_to_new_buffer(&asn_DEF_«$name»,
  50.162 -                    NULL, msg, (void **) &payload);
  50.163 -            if (size == -1) {
  50.164 -                status = PEP_CANNOT_ENCODE;
  50.165 -                goto error;
  50.166 -            }
  50.167 -
  50.168 -            status = prepare_message(me, partner, payload, size, &_message);
  50.169 -            if (status != PEP_STATUS_OK)
  50.170 -                goto error;
  50.171 -            payload = NULL;
  50.172 -
  50.173 -            free_identity(me);
  50.174 -            me = NULL;
  50.175 -
  50.176 -            status = session->messageToSend(session->«$filename»_obj, _message);
  50.177 -
  50.178 -            free_message(_message);
  50.179 -            ASN_STRUCT_FREE(asn_DEF_«$name», msg);
  50.180 -
  50.181 -            return status;
  50.182 +            `` if "$name='GroupKeys'" |> free_identity_list(kl);
  50.183 +            free_DeviceGroup_Protocol_msg(msg);
  50.184 +            return PEP_STATUS_OK;
  50.185  
  50.186          enomem:
  50.187              status = PEP_OUT_OF_MEMORY;
  50.188          error:
  50.189 -            ASN_STRUCT_FREE(asn_DEF_«$name», msg);
  50.190 -            free(payload);
  50.191 -            free_message(_message);
  50.192 -            free_identity(me);
  50.193 +            free_DeviceGroup_Protocol_msg(msg);
  50.194 +            `` if "$name='GroupKeys'" |> free_identity_list(kl);
  50.195              return status;
  50.196          }
  50.197  
    51.1 --- a/sync/gen_statemachine.ysl2	Mon Oct 03 14:34:58 2016 +0200
    51.2 +++ b/sync/gen_statemachine.ysl2	Wed Oct 05 15:38:42 2016 +0200
    51.3 @@ -28,7 +28,7 @@
    51.4  
    51.5          // state machine for «@name»
    51.6  
    51.7 -        #include "pEpEngine.h"
    51.8 +        #include "message_api.h"
    51.9          
   51.10          #ifdef __cplusplus
   51.11          extern "C" {
   51.12 @@ -37,26 +37,45 @@
   51.13          // types
   51.14  
   51.15          typedef pEp_identity * Identity;
   51.16 -        typedef union _param { const Identity partner; const stringlist_t *keylist; } param_t;
   51.17 +        typedef stringlist_t * Stringlist;
   51.18 +        typedef union _param { Identity partner; stringlist_t *keylist; } param_t;
   51.19  
   51.20          // error values
   51.21  
   51.22          typedef enum _fsm_error {
   51.23 +            // these error values are corresponding to
   51.24 +            // PEP_SYNC_STATEMACHINE_ERROR - value
   51.25              invalid_state = -2,
   51.26 -            invalid_event = -3
   51.27 +            invalid_event = -3,
   51.28 +            invalid_condition = -4,
   51.29 +            invalid_action = -5,
   51.30 +
   51.31 +            // out of memory condition
   51.32 +            invalid_out_of_memory = -128
   51.33          } fsm_error;
   51.34  
   51.35 +        // conditions
   51.36 +
   51.37 +        `` for "func:distinctName(condition)" | int «@name»(PEP_SESSION session`apply "parm", 0`);
   51.38 +
   51.39          // states
   51.40  
   51.41          typedef enum _«@name»_state {
   51.42 -            «@name»_state_NONE = -1,
   51.43 +            // error values also in this namespace
   51.44 +            «@name»_state_invalid_state = (int) invalid_state,
   51.45 +            «@name»_state_invalid_event = (int) invalid_event,
   51.46 +            «@name»_state_invalid_condition = (int) invalid_condition,
   51.47 +            «@name»_state_invalid_action = (int) invalid_action,
   51.48 +            «@name»_state_invalid_out_of_memory = (int) invalid_out_of_memory,
   51.49 +
   51.50 +            «@name»_state_NONE = 0,
   51.51          `` for "func:distinctName(state)" |> «@name»`if "position()!=last()" > , `
   51.52          } «@name»_state;
   51.53  
   51.54          // events
   51.55  
   51.56          typedef enum _«@name»_event {
   51.57 -            «@name»_event_NONE = -1,
   51.58 +            «@name»_event_NONE = 0,
   51.59          ||
   51.60          for "func:distinctName(state/event[not(not(/protocol/fsm/tag/@name=@name))])" {
   51.61              const "name", "@name";
   51.62 @@ -70,7 +89,24 @@
   51.63          // actions
   51.64  
   51.65          `` const "name", "@name"
   51.66 -        `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, const Identity partner);
   51.67 +        `` for "func:distinctName(//action)" | PEP_STATUS «@name»(PEP_SESSION session, «$name»_state state, Identity partner, void *extra);
   51.68 +
   51.69 +        // event injector
   51.70 +
   51.71 +        PEP_STATUS inject_DeviceState_event(
   51.72 +            PEP_SESSION session, 
   51.73 +            DeviceState_event event,
   51.74 +            Identity partner,
   51.75 +            void *extra);
   51.76 +
   51.77 +        // message receiver
   51.78 +        
   51.79 +        PEP_STATUS receive_DeviceState_msg(
   51.80 +                PEP_SESSION session, 
   51.81 +                message *src, 
   51.82 +                PEP_rating rating, 
   51.83 +                stringlist_t *keylist
   51.84 +            );
   51.85  
   51.86          // state machine
   51.87  
   51.88 @@ -78,8 +114,8 @@
   51.89                  PEP_SESSION session,
   51.90                  «@name»_state state,
   51.91                  «@name»_event event,
   51.92 -                const Identity partner,
   51.93 -                «@name»_state state_partner
   51.94 +                Identity partner,
   51.95 +                void *extra
   51.96              );
   51.97  
   51.98          // driver
   51.99 @@ -88,7 +124,7 @@
  51.100                  PEP_SESSION session,
  51.101                  «@name»_event event,
  51.102                  Identity partner,
  51.103 -                «@name»_state state_partner
  51.104 +                void *extra
  51.105              );
  51.106  
  51.107          #ifdef __cplusplus
  51.108 @@ -109,15 +145,33 @@
  51.109                  PEP_SESSION session,
  51.110                  «@name»_event event,
  51.111                  Identity partner,
  51.112 -                «@name»_state state_partner
  51.113 +                void *extra
  51.114              )
  51.115          {
  51.116 -            PEP_STATUS status = PEP_STATUS_OK;
  51.117 +            assert(session);
  51.118 +            if (!session)
  51.119 +                return PEP_ILLEGAL_VALUE;
  51.120  
  51.121 -            session->«@filename»_state = fsm_«@name»(session, session->«@filename»_state,
  51.122 -                    event, partner, state_partner);
  51.123 +            while(true)
  51.124 +            {
  51.125 +                «@name»_state new_state = fsm_«@name»(session,
  51.126 +                    session->«@filename»_state, event, partner, extra);
  51.127  
  51.128 -            return status;
  51.129 +                if (new_state == «@name»_state_invalid_out_of_memory)
  51.130 +                    return PEP_OUT_OF_MEMORY;
  51.131 +
  51.132 +                if (new_state < 0)
  51.133 +                    return PEP_SYNC_STATEMACHINE_ERROR - new_state;
  51.134 +                
  51.135 +                if (new_state == session->«@filename»_state)
  51.136 +                    break;
  51.137 +
  51.138 +                event = Init;
  51.139 +                extra = NULL;
  51.140 +                session->«@filename»_state = new_state;
  51.141 +            } 
  51.142 +
  51.143 +            return PEP_STATUS_OK;
  51.144          }
  51.145  
  51.146          ||
  51.147 @@ -131,12 +185,15 @@
  51.148                  PEP_SESSION session,
  51.149                  «@name»_state state,
  51.150                  «@name»_event event,
  51.151 -                const Identity partner,
  51.152 -                «@name»_state state_partner
  51.153 +                Identity partner,
  51.154 +                void *extra
  51.155              )
  51.156          {
  51.157 +            int cond_result;
  51.158 +            PEP_STATUS status = PEP_STATUS_OK;
  51.159 +
  51.160              switch (state) {
  51.161 -                `` apply "state"
  51.162 +            `` apply "state", 2
  51.163                  default:
  51.164                      return («@name»_state) invalid_state;
  51.165              }
  51.166 @@ -151,9 +208,10 @@
  51.167      ||
  51.168      case «@name»:
  51.169          switch (event) {
  51.170 +        `` if "not(event[@name='Init'])" |>> case Init: break;
  51.171          `` apply "event", 2
  51.172 -        default:
  51.173 -            return («../@name»_state) invalid_event;
  51.174 +            default:
  51.175 +                return («../@name»_state) invalid_event;
  51.176          }
  51.177          break;
  51.178  
  51.179 @@ -162,18 +220,42 @@
  51.180      template "event"
  51.181      ||
  51.182      case «@name»:
  51.183 -    `` apply "action|transition";
  51.184 +    `` apply "action|transition|condition";
  51.185      `` if "name(*[position()=last()]) != 'transition'" |> break;
  51.186      ||
  51.187  
  51.188      template "action" {
  51.189          indent(0);
  51.190 -        > «@name»(session, state, 
  51.191 +        > status = «@name»(session, state, 
  51.192          choose {
  51.193              when "parm" > «name(parm/*)»
  51.194              otherwise > NULL
  51.195          }
  51.196 +        choose {
  51.197 +            when "parm[2]" > , extra /*«name(parm[2]/*)»*/
  51.198 +            otherwise > , NULL
  51.199 +        }
  51.200          > );\n
  51.201 +        | if (status == PEP_OUT_OF_MEMORY)
  51.202 +        |> return (int) invalid_out_of_memory;
  51.203 +        | if (status != PEP_STATUS_OK)
  51.204 +        |> return (int) invalid_action;
  51.205 +    }
  51.206 +
  51.207 +    template "condition" {
  51.208 +        | cond_result = «@name»(session`apply "parm", 0`);
  51.209 +        | if (cond_result < 0)
  51.210 +        |> return cond_result;
  51.211 +        | if (cond_result) {
  51.212 +        apply "action|transition|condition";
  51.213 +        | }
  51.214 +    }
  51.215 +
  51.216 +    template "parm" choose {
  51.217 +        when "count(*) = 1"
  51.218 +            > , «name(*)»
  51.219 +        otherwise
  51.220 +            > , «name(*[1])» «name(*[2])»
  51.221      }
  51.222  
  51.223      template "transition" | return «@target»;
    52.1 --- a/test/Makefile	Mon Oct 03 14:34:58 2016 +0200
    52.2 +++ b/test/Makefile	Wed Oct 05 15:38:42 2016 +0200
    52.3 @@ -4,7 +4,7 @@
    52.4  CXX?=g++ -std=gnu++11 -pthread
    52.5  LD?=$(CXX)
    52.6  LDFLAGS?=-L$(HOME)/lib
    52.7 -LDLIBS?=-letpan -lpEpEngine -lstdc++ -L../asn.1 -lasn1
    52.8 +LDLIBS?=-letpan -lpEpEngine -lstdc++ -L../asn.1 -lasn1 -luuid
    52.9  CXXFLAGS?=-std=c++11 -g -O0 -I../src -I../asn.1
   52.10  # CXXFLAGS=-O3 -DNDEBUG
   52.11  
    53.1 --- a/test/_test_template_cc	Mon Oct 03 14:34:58 2016 +0200
    53.2 +++ b/test/_test_template_cc	Wed Oct 05 15:38:42 2016 +0200
    53.3 @@ -1,6 +1,7 @@
    53.4  #include <iostream>
    53.5  #include <string>
    53.6  #include <assert.h>
    53.7 +#include "pEpEngine_test.h"
    53.8  #include "MODULE.h"
    53.9  
   53.10  using namespace std;
   53.11 @@ -12,7 +13,7 @@
   53.12      
   53.13      cout << "calling init()\n";
   53.14      PEP_STATUS status1 = init(&session);   
   53.15 -    assert(status1 == PEP_STATUS_OK);
   53.16 +    ASSERT_STATUS(status1);
   53.17      assert(session);
   53.18      cout << "init() completed.\n";
   53.19  
    54.1 --- a/test/encrypt_for_identity_test.cc	Mon Oct 03 14:34:58 2016 +0200
    54.2 +++ b/test/encrypt_for_identity_test.cc	Wed Oct 05 15:38:42 2016 +0200
    54.3 @@ -74,14 +74,14 @@
    54.4      message* decrypted_msg = nullptr;
    54.5      stringlist_t* keylist_used = nullptr;
    54.6  
    54.7 -    PEP_color color;
    54.8 +    PEP_rating rating;
    54.9      PEP_decrypt_flags_t flags;
   54.10  
   54.11 -    status = decrypt_message(session, encrypted_msg, &decrypted_msg, &keylist_used, &color, &flags);
   54.12 +    status = decrypt_message(session, encrypted_msg, &decrypted_msg, &keylist_used, &rating, &flags);
   54.13      assert(status == PEP_STATUS_OK);
   54.14      assert(decrypted_msg);
   54.15      assert(keylist_used);
   54.16 -    assert(color);
   54.17 +    assert(rating);
   54.18      PEP_comm_type ct = encrypted_msg->from->comm_type;
   54.19      assert(ct == PEP_ct_pEp || ct == PEP_ct_pEp_unconfirmed || ct == PEP_ct_OpenPGP || ct == PEP_ct_OpenPGP_unconfirmed );
   54.20  
    55.1 --- a/test/map_asn1_test.cc	Mon Oct 03 14:34:58 2016 +0200
    55.2 +++ b/test/map_asn1_test.cc	Wed Oct 05 15:38:42 2016 +0200
    55.3 @@ -41,36 +41,6 @@
    55.4      free_identity(ident1);
    55.5      free_identity(ident2);
    55.6  
    55.7 -    cout << "creating new stringlist...\n";
    55.8 -
    55.9 -    stringlist_t *sl = new_stringlist("23");
   55.10 -    assert(sl);
   55.11 -    stringlist_t *_sl = stringlist_add(sl, "42");
   55.12 -    assert(_sl);
   55.13 -
   55.14 -    cout << "converting stringlist to keylist...\n";
   55.15 -
   55.16 -    KeyList_t *kl = KeyList_from_stringlist(sl, NULL);
   55.17 -    assert(kl);
   55.18 -
   55.19 -    cout << "converting keylist to stringlist...\n";
   55.20 -
   55.21 -    stringlist_t *sl2 = KeyList_to_stringlist(kl, NULL);
   55.22 -    assert(sl2);
   55.23 -
   55.24 -    stringlist_t *_sl2;
   55.25 -    for (_sl = sl, _sl2 = sl2; _sl && _sl->value; _sl = _sl->next, _sl2 = _sl2->next) {
   55.26 -        assert(_sl2);
   55.27 -        assert(_sl2->value);
   55.28 -        assert(strcmp(_sl->value, _sl2->value) == 0);
   55.29 -        assert(!_sl->next == !_sl2->next);
   55.30 -    }
   55.31 -
   55.32 -    cout << "freeing lists...\n";
   55.33 -
   55.34 -    free_stringlist(sl);
   55.35 -    free_stringlist(sl2);
   55.36 -    ASN_STRUCT_FREE(asn_DEF_KeyList, kl);
   55.37  
   55.38      return 0;
   55.39  }
    56.1 --- a/test/message_api_test.cc	Mon Oct 03 14:34:58 2016 +0200
    56.2 +++ b/test/message_api_test.cc	Wed Oct 05 15:38:42 2016 +0200
    56.3 @@ -49,7 +49,7 @@
    56.4      cout << "encrypting message as MIME multipart…\n";
    56.5      message *enc_msg2 = nullptr;
    56.6      cout << "calling encrypt_message()\n";
    56.7 -    status2 = encrypt_message(session, msg2, NULL, &enc_msg2, PEP_enc_PGP_MIME);
    56.8 +    status2 = encrypt_message(session, msg2, NULL, &enc_msg2, PEP_enc_PGP_MIME, 0);
    56.9      cout << "encrypt_message() returns " << status2 << '.' << endl;
   56.10      assert(status2 == PEP_STATUS_OK);
   56.11      assert(enc_msg2);
   56.12 @@ -75,14 +75,14 @@
   56.13  
   56.14      message *msg4 = nullptr;
   56.15      stringlist_t *keylist4 = nullptr;
   56.16 -    PEP_color color;
   56.17 +    PEP_rating rating;
   56.18      PEP_decrypt_flags_t flags;
   56.19      
   56.20 -    PEP_STATUS status4 = decrypt_message(session, enc_msg2, &msg4, &keylist4, &color, &flags);
   56.21 +    PEP_STATUS status4 = decrypt_message(session, enc_msg2, &msg4, &keylist4, &rating, &flags);
   56.22      assert(status4 == PEP_STATUS_OK);
   56.23      assert(msg4);
   56.24      assert(keylist4);
   56.25 -    assert(color);
   56.26 +    assert(rating);
   56.27      PEP_comm_type ct = enc_msg2->from->comm_type;
   56.28      assert(ct == PEP_ct_pEp || ct == PEP_ct_pEp_unconfirmed || ct == PEP_ct_OpenPGP || ct == PEP_ct_OpenPGP_unconfirmed );
   56.29  
   56.30 @@ -119,14 +119,14 @@
   56.31  
   56.32      message *msg6 = nullptr;
   56.33      stringlist_t *keylist5 = nullptr;
   56.34 -    PEP_color color2;
   56.35 +    PEP_rating rating2;
   56.36      PEP_decrypt_flags_t flags2;
   56.37 -    PEP_STATUS status6 = decrypt_message(session, msg5, &msg6, &keylist5, &color2, &flags2);
   56.38 +    PEP_STATUS status6 = decrypt_message(session, msg5, &msg6, &keylist5, &rating2, &flags2);
   56.39      assert(status6 == PEP_DECRYPT_NO_KEY);
   56.40      assert(msg6 == NULL);
   56.41      assert(keylist5 == NULL);
   56.42 -    assert(color2 == PEP_rating_have_no_key);
   56.43 -    cout << "color :" << color2 << "\n";
   56.44 +    assert(rating2 == PEP_rating_have_no_key);
   56.45 +    cout << "rating :" << rating2 << "\n";
   56.46      free_stringlist(keylist5);
   56.47  
   56.48      cout << "freeing messages…\n";
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/test/pEpEngine_test.h	Wed Oct 05 15:38:42 2016 +0200
    57.3 @@ -0,0 +1,4 @@
    57.4 +#include <iomanip>
    57.5 +
    57.6 +#define ASSERT_STATUS(status) { cout << setfill('0') << "status: 0x" << hex << setw(4) << status << "\n"; assert(status == PEP_STATUS_OK); }
    57.7 +
    58.1 --- a/test/revoke_regen_attach_test.cc	Mon Oct 03 14:34:58 2016 +0200
    58.2 +++ b/test/revoke_regen_attach_test.cc	Wed Oct 05 15:38:42 2016 +0200
    58.3 @@ -39,7 +39,7 @@
    58.4      
    58.5      cout << "revoke \n";
    58.6      
    58.7 -    key_compromized(session, me);
    58.8 +    key_mistrusted(session, me);
    58.9  
   58.10      cout << "re-generated fingerprint \n";
   58.11      cout << me->fpr << "\n";
   58.12 @@ -57,7 +57,7 @@
   58.13      cout << "encrypting message as MIME multipart…\n";
   58.14      message *enc_msg;
   58.15      cout << "calling encrypt_message()\n";
   58.16 -    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME);
   58.17 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   58.18      cout << status;
   58.19      assert(status == PEP_STATUS_OK);
   58.20      assert(enc_msg);
    59.1 --- a/test/sequence_test.cc	Mon Oct 03 14:34:58 2016 +0200
    59.2 +++ b/test/sequence_test.cc	Wed Oct 05 15:38:42 2016 +0200
    59.3 @@ -1,5 +1,6 @@
    59.4  #include <iostream>
    59.5  #include <string>
    59.6 +#include <cstring> // for std::strdup()
    59.7  #include <assert.h>
    59.8  #include "pEpEngine.h"
    59.9  
   59.10 @@ -18,18 +19,44 @@
   59.11  
   59.12      // sequence test code
   59.13  
   59.14 -    int32_t value1;
   59.15 -    PEP_STATUS status2 = sequence_value(session, "test", &value1);
   59.16 +    int32_t value1 = 0;
   59.17 +    char *name1 = strdup("test");
   59.18 +    assert(name1);
   59.19 +    PEP_STATUS status2 = sequence_value(session, name1, &value1);
   59.20      assert(status2 == PEP_STATUS_OK);
   59.21  
   59.22      cout << "test sequence: " << value1 << "\n";
   59.23  
   59.24 -    int32_t value2;
   59.25 -    PEP_STATUS status3 = sequence_value(session, "test", &value2);
   59.26 +    int32_t value2 = 0;
   59.27 +    PEP_STATUS status3 = sequence_value(session, name1, &value2);
   59.28      assert(status3 == PEP_STATUS_OK);
   59.29  
   59.30      cout << "test sequence: " << value2 << "\n";
   59.31      assert(value2 == value1 + 1);
   59.32 +//    free(name1);
   59.33 +
   59.34 +    cout << "testing sequence violation\n";
   59.35 +    int32_t value3 = value2 - 1;
   59.36 +    PEP_STATUS status4 = sequence_value(session, name1, &value3);
   59.37 +    assert(status4 == PEP_SEQUENCE_VIOLATED);
   59.38 +
   59.39 +    cout << "testing sequence non-violation\n";
   59.40 +    int32_t value4 = value2 + 1;
   59.41 +    PEP_STATUS status5 = sequence_value(session, name1, &value4);
   59.42 +    assert(status5 == PEP_STATUS_OK);
   59.43 +
   59.44 +    cout << "testing UUID generation\n";
   59.45 +    int32_t value5 = 0;
   59.46 +    char name2[37] = { 0, };
   59.47 +    PEP_STATUS status6 = sequence_value(session, name2, &value5);
   59.48 +    assert(status6 == PEP_OWN_SEQUENCE);
   59.49 +    cout << "UUID created: " << name2 << "\n";
   59.50 +
   59.51 +    cout << "set sequence value\n";
   59.52 +    int32_t value6 = value2 + 10;
   59.53 +    PEP_STATUS status7 = sequence_value(session, name1, &value6);
   59.54 +    assert(status7 == PEP_STATUS_OK);
   59.55 +    cout << "value set to " << value6 << "\n";
   59.56  
   59.57      cout << "calling release()\n";
   59.58      release(session);