Merged in sync make-cleanup
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Mon, 01 Apr 2019 20:58:40 +0200
branchmake-cleanup
changeset 3426a2dc6594b206
parent 3284 57fda9f58f7c
parent 3425 495866c118e7
child 3427 be87288f5391
Merged in sync
asn.1/Makefile
src/Makefile
test/include/test_util.h
test/src/util/test_util.cc
     1.1 --- a/.hgignore	Thu Feb 07 16:02:11 2019 +0100
     1.2 +++ b/.hgignore	Mon Apr 01 20:58:40 2019 +0200
     1.3 @@ -60,6 +60,8 @@
     1.4  test/pEp_test_home
     1.5  test/TestDriver
     1.6  test/local
     1.7 +test/include/LocalPlayground.h
     1.8 +test/src/engine_test/LocalPlayground.cc
     1.9  .tags
    1.10  */.tags
    1.11  */*/.tags
     2.1 --- a/asn.1/Makefile	Thu Feb 07 16:02:11 2019 +0100
     2.2 +++ b/asn.1/Makefile	Mon Apr 01 20:58:40 2019 +0200
     2.3 @@ -10,7 +10,7 @@
     2.4  	make libasn1.a
     2.5  
     2.6  libasn1.a: $(ALL_OBJECTS)
     2.7 -	ar -rc $@ $(ALL_OBJECTS)
     2.8 +	$(AR) -rc $@ $(ALL_OBJECTS)
     2.9  
    2.10  generate: Sync.c
    2.11  	rm -f converter-sample.c
     3.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Thu Feb 07 16:02:11 2019 +0100
     3.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Mon Apr 01 20:58:40 2019 +0200
     3.3 @@ -13,13 +13,27 @@
     3.4  		43370833203C075A004E6547 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = 4337082D203C075A004E6547 /* sqlite3.c */; };
     3.5  		43370834203C075A004E6547 /* sqlite3.h in Headers */ = {isa = PBXBuildFile; fileRef = 43370832203C075A004E6547 /* sqlite3.h */; };
     3.6  		4354FF651D6EDF300033069C /* sync_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF641D6EDF300033069C /* sync_impl.c */; };
     3.7 -		4354FF691D6EE1A70033069C /* NULL.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF681D6EE1A70033069C /* NULL.c */; };
     3.8 +		438C439B2167582500C7425B /* sync_api.h in Headers */ = {isa = PBXBuildFile; fileRef = 438C43962167582400C7425B /* sync_api.h */; };
     3.9  		438C43B52167752C00C7425B /* labeled_int_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 438C43AF2167752C00C7425B /* labeled_int_list.h */; };
    3.10  		438C43B62167752C00C7425B /* labeled_int_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 438C43B42167752C00C7425B /* labeled_int_list.c */; };
    3.11 -		43BA0F461D7964750059172F /* asn1_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = 43BA0F451D7964750059172F /* asn1_helper.c */; };
    3.12 -		43E9BC6A1DB51A1E00AD2352 /* GroupUpdate.c in Sources */ = {isa = PBXBuildFile; fileRef = 43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */; };
    3.13 -		43E9BC7F1DB6720E00AD2352 /* UpdateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = 43E9BC7E1DB6720E00AD2352 /* UpdateRequest.c */; };
    3.14  		43F6921D1F164A47009418F5 /* resource_id.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F6921C1F164A47009418F5 /* resource_id.c */; };
    3.15 +		43F73BF02166269200AB4524 /* PString.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BEB2166269200AB4524 /* PString.c */; };
    3.16 +		43F73BF2216626E100AB4524 /* Sync_func.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF1216626E100AB4524 /* Sync_func.c */; };
    3.17 +		43F73BFC216627CC00AB4524 /* CommitAccept.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF5216627CB00AB4524 /* CommitAccept.c */; };
    3.18 +		43F73BFD216627CC00AB4524 /* TID.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF6216627CC00AB4524 /* TID.c */; };
    3.19 +		43F73BFE216627CC00AB4524 /* KeySync.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF7216627CC00AB4524 /* KeySync.c */; };
    3.20 +		43F73BFF216627CC00AB4524 /* GroupKeysAndClose.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF8216627CC00AB4524 /* GroupKeysAndClose.c */; };
    3.21 +		43F73C00216627CC00AB4524 /* Rollback.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BF9216627CC00AB4524 /* Rollback.c */; };
    3.22 +		43F73C01216627CC00AB4524 /* HandshakeAnswer.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BFA216627CC00AB4524 /* HandshakeAnswer.c */; };
    3.23 +		43F73C02216627CC00AB4524 /* CommitReject.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73BFB216627CC00AB4524 /* CommitReject.c */; };
    3.24 +		43F73C0B2166282C00AB4524 /* openpgp_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C032166282C00AB4524 /* openpgp_compat.c */; };
    3.25 +		43F73C0C2166282C00AB4524 /* Sync_event.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C042166282C00AB4524 /* Sync_event.c */; };
    3.26 +		43F73C0D2166282C00AB4524 /* key_reset.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C052166282C00AB4524 /* key_reset.c */; };
    3.27 +		43F73C0E2166282C00AB4524 /* sync_codec.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C062166282C00AB4524 /* sync_codec.c */; };
    3.28 +		43F73C0F2166282C00AB4524 /* KeySync_fsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C072166282C00AB4524 /* KeySync_fsm.c */; };
    3.29 +		43F73C112166282C00AB4524 /* sync_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C092166282C00AB4524 /* sync_api.c */; };
    3.30 +		43F73C122166282C00AB4524 /* growing_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C0A2166282C00AB4524 /* growing_buf.c */; };
    3.31 +		43F73C14216628CA00AB4524 /* Sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F73C13216628CA00AB4524 /* Sync.c */; };
    3.32  		6400FB861B8CA1C6005221E3 /* libnetpgp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 645922521B8BD32B00A5AF93 /* libnetpgp.a */; };
    3.33  		6400FB8B1B8CA1CF005221E3 /* libetpan-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64289E371B8B630200FC617B /* libetpan-ios.a */; };
    3.34  		644297C51BE11CE0002BC73B /* system.db in Resources */ = {isa = PBXBuildFile; fileRef = 64951A1B1BE0FCD800B10E71 /* system.db */; };
    3.35 @@ -61,8 +75,6 @@
    3.36  		646C410B1D510CD800C63EFF /* constraints.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B61D510CD700C63EFF /* constraints.h */; };
    3.37  		646C410C1D510CD800C63EFF /* der_encoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B71D510CD700C63EFF /* der_encoder.c */; };
    3.38  		646C410D1D510CD800C63EFF /* der_encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40B81D510CD700C63EFF /* der_encoder.h */; };
    3.39 -		646C410E1D510CD800C63EFF /* DeviceGroup-Protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */; };
    3.40 -		646C410F1D510CD800C63EFF /* DeviceGroup-Protocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */; };
    3.41  		646C41101D510CD800C63EFF /* GroupKeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40BB1D510CD700C63EFF /* GroupKeys.c */; };
    3.42  		646C41111D510CD800C63EFF /* GroupKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40BC1D510CD700C63EFF /* GroupKeys.h */; };
    3.43  		646C41121D510CD800C63EFF /* HandshakeRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40BD1D510CD700C63EFF /* HandshakeRequest.c */; };
    3.44 @@ -95,8 +107,6 @@
    3.45  		646C412F1D510CD800C63EFF /* per_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DA1D510CD800C63EFF /* per_support.h */; };
    3.46  		646C41301D510CD800C63EFF /* PrintableString.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40DB1D510CD800C63EFF /* PrintableString.c */; };
    3.47  		646C41311D510CD800C63EFF /* PrintableString.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DC1D510CD800C63EFF /* PrintableString.h */; };
    3.48 -		646C41321D510CD800C63EFF /* Sync-Protocols.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40DE1D510CD800C63EFF /* Sync-Protocols.c */; };
    3.49 -		646C41331D510CD800C63EFF /* Sync-Protocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40DF1D510CD800C63EFF /* Sync-Protocols.h */; };
    3.50  		646C41341D510CD800C63EFF /* UTF8String.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E01D510CD800C63EFF /* UTF8String.c */; };
    3.51  		646C41351D510CD800C63EFF /* UTF8String.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E11D510CD800C63EFF /* UTF8String.h */; };
    3.52  		646C41361D510CD800C63EFF /* Version.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E21D510CD800C63EFF /* Version.c */; };
    3.53 @@ -108,12 +118,6 @@
    3.54  		646C413C1D510CD800C63EFF /* xer_support.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C40E81D510CD800C63EFF /* xer_support.c */; };
    3.55  		646C413D1D510CD800C63EFF /* xer_support.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C40E91D510CD800C63EFF /* xer_support.h */; };
    3.56  		646C41451D510D2C00C63EFF /* sync_actions.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C413E1D510D2C00C63EFF /* sync_actions.c */; };
    3.57 -		646C41461D510D2C00C63EFF /* sync_driver.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C413F1D510D2C00C63EFF /* sync_driver.c */; };
    3.58 -		646C41471D510D2C00C63EFF /* sync_fsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41401D510D2C00C63EFF /* sync_fsm.c */; };
    3.59 -		646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C41411D510D2C00C63EFF /* sync_fsm.h */; };
    3.60 -		646C41491D510D2C00C63EFF /* sync_send_actions.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41421D510D2C00C63EFF /* sync_send_actions.c */; };
    3.61 -		646C414A1D510D2C00C63EFF /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C41431D510D2C00C63EFF /* sync.c */; };
    3.62 -		646C414B1D510D2C00C63EFF /* sync.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C41441D510D2C00C63EFF /* sync.h */; };
    3.63  		646C414E1D510D8800C63EFF /* baseprotocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C414C1D510D8800C63EFF /* baseprotocol.c */; };
    3.64  		646C414F1D510D8800C63EFF /* baseprotocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 646C414D1D510D8800C63EFF /* baseprotocol.h */; };
    3.65  		649DE08B1B45C19100912F72 /* libcurl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649DE08A1B45C19100912F72 /* libcurl.a */; };
    3.66 @@ -202,15 +206,28 @@
    3.67  		430D258A1C9ED75A00B94535 /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../src/blacklist.c; sourceTree = "<group>"; };
    3.68  		4337082D203C075A004E6547 /* sqlite3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sqlite3.c; path = ../src/sqlite3.c; sourceTree = "<group>"; };
    3.69  		43370832203C075A004E6547 /* sqlite3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sqlite3.h; path = ../src/sqlite3.h; sourceTree = "<group>"; };
    3.70 -		4346F86A1ECB38E700381CBE /* sync_app.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sync_app.h; path = ../src/sync_app.h; sourceTree = "<group>"; };
    3.71  		4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
    3.72 -		4354FF681D6EE1A70033069C /* NULL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NULL.c; path = ../asn.1/NULL.c; sourceTree = "<group>"; };
    3.73 +		438C43962167582400C7425B /* sync_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync_api.h; path = ../src/sync_api.h; sourceTree = "<group>"; };
    3.74  		438C43AF2167752C00C7425B /* labeled_int_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = labeled_int_list.h; path = ../src/labeled_int_list.h; sourceTree = "<group>"; };
    3.75  		438C43B42167752C00C7425B /* labeled_int_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = labeled_int_list.c; path = ../src/labeled_int_list.c; sourceTree = "<group>"; };
    3.76 -		43BA0F451D7964750059172F /* asn1_helper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = asn1_helper.c; path = ../src/asn1_helper.c; sourceTree = "<group>"; };
    3.77 -		43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupUpdate.c; path = ../asn.1/GroupUpdate.c; sourceTree = "<group>"; };
    3.78 -		43E9BC7E1DB6720E00AD2352 /* UpdateRequest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = UpdateRequest.c; path = ../asn.1/UpdateRequest.c; sourceTree = "<group>"; };
    3.79  		43F6921C1F164A47009418F5 /* resource_id.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = resource_id.c; path = ../src/resource_id.c; sourceTree = "<group>"; };
    3.80 +		43F73BEB2166269200AB4524 /* PString.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PString.c; path = ../asn.1/PString.c; sourceTree = "<group>"; };
    3.81 +		43F73BF1216626E100AB4524 /* Sync_func.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Sync_func.c; path = ../src/Sync_func.c; sourceTree = "<group>"; };
    3.82 +		43F73BF5216627CB00AB4524 /* CommitAccept.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CommitAccept.c; path = ../asn.1/CommitAccept.c; sourceTree = "<group>"; };
    3.83 +		43F73BF6216627CC00AB4524 /* TID.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TID.c; path = ../asn.1/TID.c; sourceTree = "<group>"; };
    3.84 +		43F73BF7216627CC00AB4524 /* KeySync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = KeySync.c; path = ../asn.1/KeySync.c; sourceTree = "<group>"; };
    3.85 +		43F73BF8216627CC00AB4524 /* GroupKeysAndClose.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupKeysAndClose.c; path = ../asn.1/GroupKeysAndClose.c; sourceTree = "<group>"; };
    3.86 +		43F73BF9216627CC00AB4524 /* Rollback.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Rollback.c; path = ../asn.1/Rollback.c; sourceTree = "<group>"; };
    3.87 +		43F73BFA216627CC00AB4524 /* HandshakeAnswer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = HandshakeAnswer.c; path = ../asn.1/HandshakeAnswer.c; sourceTree = "<group>"; };
    3.88 +		43F73BFB216627CC00AB4524 /* CommitReject.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = CommitReject.c; path = ../asn.1/CommitReject.c; sourceTree = "<group>"; };
    3.89 +		43F73C032166282C00AB4524 /* openpgp_compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = openpgp_compat.c; path = ../src/openpgp_compat.c; sourceTree = "<group>"; };
    3.90 +		43F73C042166282C00AB4524 /* Sync_event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Sync_event.c; path = ../src/Sync_event.c; sourceTree = "<group>"; };
    3.91 +		43F73C052166282C00AB4524 /* key_reset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = key_reset.c; path = ../src/key_reset.c; sourceTree = "<group>"; };
    3.92 +		43F73C062166282C00AB4524 /* sync_codec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_codec.c; path = ../src/sync_codec.c; sourceTree = "<group>"; };
    3.93 +		43F73C072166282C00AB4524 /* KeySync_fsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = KeySync_fsm.c; path = ../src/KeySync_fsm.c; sourceTree = "<group>"; };
    3.94 +		43F73C092166282C00AB4524 /* sync_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_api.c; path = ../src/sync_api.c; sourceTree = "<group>"; };
    3.95 +		43F73C0A2166282C00AB4524 /* growing_buf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = growing_buf.c; path = ../src/growing_buf.c; sourceTree = "<group>"; };
    3.96 +		43F73C13216628CA00AB4524 /* Sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Sync.c; path = ../asn.1/Sync.c; sourceTree = "<group>"; };
    3.97  		644297BF1BE11C65002BC73B /* pEpTrustWords.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = pEpTrustWords.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
    3.98  		644297C11BE11C65002BC73B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
    3.99  		646788871CEB3D120001F54C /* map_asn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = map_asn1.c; path = ../src/map_asn1.c; sourceTree = "<group>"; };
   3.100 @@ -251,8 +268,6 @@
   3.101  		646C40B61D510CD700C63EFF /* constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constraints.h; path = ../asn.1/constraints.h; sourceTree = "<group>"; };
   3.102  		646C40B71D510CD700C63EFF /* der_encoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_encoder.c; path = ../asn.1/der_encoder.c; sourceTree = "<group>"; };
   3.103  		646C40B81D510CD700C63EFF /* der_encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_encoder.h; path = ../asn.1/der_encoder.h; sourceTree = "<group>"; };
   3.104 -		646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "DeviceGroup-Protocol.c"; path = "../asn.1/DeviceGroup-Protocol.c"; sourceTree = "<group>"; };
   3.105 -		646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "DeviceGroup-Protocol.h"; path = "../asn.1/DeviceGroup-Protocol.h"; sourceTree = "<group>"; };
   3.106  		646C40BB1D510CD700C63EFF /* GroupKeys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupKeys.c; path = ../asn.1/GroupKeys.c; sourceTree = "<group>"; };
   3.107  		646C40BC1D510CD700C63EFF /* GroupKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupKeys.h; path = ../asn.1/GroupKeys.h; sourceTree = "<group>"; };
   3.108  		646C40BD1D510CD700C63EFF /* HandshakeRequest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = HandshakeRequest.c; path = ../asn.1/HandshakeRequest.c; sourceTree = "<group>"; };
   3.109 @@ -285,9 +300,6 @@
   3.110  		646C40DA1D510CD800C63EFF /* per_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = per_support.h; path = ../asn.1/per_support.h; sourceTree = "<group>"; };
   3.111  		646C40DB1D510CD800C63EFF /* PrintableString.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = PrintableString.c; path = ../asn.1/PrintableString.c; sourceTree = "<group>"; };
   3.112  		646C40DC1D510CD800C63EFF /* PrintableString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrintableString.h; path = ../asn.1/PrintableString.h; sourceTree = "<group>"; };
   3.113 -		646C40DD1D510CD800C63EFF /* protocols.asn1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = protocols.asn1; path = ../asn.1/protocols.asn1; sourceTree = "<group>"; };
   3.114 -		646C40DE1D510CD800C63EFF /* Sync-Protocols.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "Sync-Protocols.c"; path = "../asn.1/Sync-Protocols.c"; sourceTree = "<group>"; };
   3.115 -		646C40DF1D510CD800C63EFF /* Sync-Protocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Sync-Protocols.h"; path = "../asn.1/Sync-Protocols.h"; sourceTree = "<group>"; };
   3.116  		646C40E01D510CD800C63EFF /* UTF8String.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = UTF8String.c; path = ../asn.1/UTF8String.c; sourceTree = "<group>"; };
   3.117  		646C40E11D510CD800C63EFF /* UTF8String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UTF8String.h; path = ../asn.1/UTF8String.h; sourceTree = "<group>"; };
   3.118  		646C40E21D510CD800C63EFF /* Version.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Version.c; path = ../asn.1/Version.c; sourceTree = "<group>"; };
   3.119 @@ -299,12 +311,6 @@
   3.120  		646C40E81D510CD800C63EFF /* xer_support.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xer_support.c; path = ../asn.1/xer_support.c; sourceTree = "<group>"; };
   3.121  		646C40E91D510CD800C63EFF /* xer_support.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = xer_support.h; path = ../asn.1/xer_support.h; sourceTree = "<group>"; };
   3.122  		646C413E1D510D2C00C63EFF /* sync_actions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_actions.c; path = ../src/sync_actions.c; sourceTree = "<group>"; };
   3.123 -		646C413F1D510D2C00C63EFF /* sync_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_driver.c; path = ../src/sync_driver.c; sourceTree = "<group>"; };
   3.124 -		646C41401D510D2C00C63EFF /* sync_fsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_fsm.c; path = ../src/sync_fsm.c; sourceTree = "<group>"; };
   3.125 -		646C41411D510D2C00C63EFF /* sync_fsm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync_fsm.h; path = ../src/sync_fsm.h; sourceTree = "<group>"; };
   3.126 -		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>"; };
   3.127 -		646C41431D510D2C00C63EFF /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = ../src/sync.c; sourceTree = "<group>"; };
   3.128 -		646C41441D510D2C00C63EFF /* sync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync.h; path = ../src/sync.h; sourceTree = "<group>"; };
   3.129  		646C414C1D510D8800C63EFF /* baseprotocol.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = baseprotocol.c; path = ../src/baseprotocol.c; sourceTree = "<group>"; };
   3.130  		646C414D1D510D8800C63EFF /* baseprotocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = baseprotocol.h; path = ../src/baseprotocol.h; sourceTree = "<group>"; };
   3.131  		64796A3F1B455AA5004B1C24 /* libpEpEngine.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpEpEngine.a; sourceTree = BUILT_PRODUCTS_DIR; };
   3.132 @@ -380,9 +386,15 @@
   3.133  		6406CE811CE382F400C14D77 /* asn.1 */ = {
   3.134  			isa = PBXGroup;
   3.135  			children = (
   3.136 -				43E9BC7E1DB6720E00AD2352 /* UpdateRequest.c */,
   3.137 -				43E9BC691DB51A1E00AD2352 /* GroupUpdate.c */,
   3.138 -				4354FF681D6EE1A70033069C /* NULL.c */,
   3.139 +				43F73C13216628CA00AB4524 /* Sync.c */,
   3.140 +				43F73BF5216627CB00AB4524 /* CommitAccept.c */,
   3.141 +				43F73BFB216627CC00AB4524 /* CommitReject.c */,
   3.142 +				43F73BF8216627CC00AB4524 /* GroupKeysAndClose.c */,
   3.143 +				43F73BFA216627CC00AB4524 /* HandshakeAnswer.c */,
   3.144 +				43F73BF7216627CC00AB4524 /* KeySync.c */,
   3.145 +				43F73BF9216627CC00AB4524 /* Rollback.c */,
   3.146 +				43F73BF6216627CC00AB4524 /* TID.c */,
   3.147 +				43F73BEB2166269200AB4524 /* PString.c */,
   3.148  				646C40951D510CD700C63EFF /* asn_application.h */,
   3.149  				646C40961D510CD700C63EFF /* asn_codecs_prim.c */,
   3.150  				646C40971D510CD700C63EFF /* asn_codecs_prim.h */,
   3.151 @@ -419,8 +431,6 @@
   3.152  				646C40B61D510CD700C63EFF /* constraints.h */,
   3.153  				646C40B71D510CD700C63EFF /* der_encoder.c */,
   3.154  				646C40B81D510CD700C63EFF /* der_encoder.h */,
   3.155 -				646C40B91D510CD700C63EFF /* DeviceGroup-Protocol.c */,
   3.156 -				646C40BA1D510CD700C63EFF /* DeviceGroup-Protocol.h */,
   3.157  				646C40BB1D510CD700C63EFF /* GroupKeys.c */,
   3.158  				646C40BC1D510CD700C63EFF /* GroupKeys.h */,
   3.159  				646C40BD1D510CD700C63EFF /* HandshakeRequest.c */,
   3.160 @@ -453,9 +463,6 @@
   3.161  				646C40DA1D510CD800C63EFF /* per_support.h */,
   3.162  				646C40DB1D510CD800C63EFF /* PrintableString.c */,
   3.163  				646C40DC1D510CD800C63EFF /* PrintableString.h */,
   3.164 -				646C40DD1D510CD800C63EFF /* protocols.asn1 */,
   3.165 -				646C40DE1D510CD800C63EFF /* Sync-Protocols.c */,
   3.166 -				646C40DF1D510CD800C63EFF /* Sync-Protocols.h */,
   3.167  				646C40E01D510CD800C63EFF /* UTF8String.c */,
   3.168  				646C40E11D510CD800C63EFF /* UTF8String.h */,
   3.169  				646C40E21D510CD800C63EFF /* Version.c */,
   3.170 @@ -526,23 +533,24 @@
   3.171  				C46EBAEC216E445F0042A6A3 /* base64.h */,
   3.172  				438C43B42167752C00C7425B /* labeled_int_list.c */,
   3.173  				438C43AF2167752C00C7425B /* labeled_int_list.h */,
   3.174 +				438C43962167582400C7425B /* sync_api.h */,
   3.175 +				43F73C0A2166282C00AB4524 /* growing_buf.c */,
   3.176 +				43F73C052166282C00AB4524 /* key_reset.c */,
   3.177 +				43F73C072166282C00AB4524 /* KeySync_fsm.c */,
   3.178 +				43F73C032166282C00AB4524 /* openpgp_compat.c */,
   3.179 +				43F73C092166282C00AB4524 /* sync_api.c */,
   3.180 +				43F73C062166282C00AB4524 /* sync_codec.c */,
   3.181 +				43F73C042166282C00AB4524 /* Sync_event.c */,
   3.182 +				43F73BF1216626E100AB4524 /* Sync_func.c */,
   3.183  				4337082D203C075A004E6547 /* sqlite3.c */,
   3.184  				43370832203C075A004E6547 /* sqlite3.h */,
   3.185  				430BCC472015EE800077E998 /* pEp_string.c */,
   3.186  				430BCC462015EE800077E998 /* pEp_string.h */,
   3.187  				43F6921C1F164A47009418F5 /* resource_id.c */,
   3.188 -				43BA0F451D7964750059172F /* asn1_helper.c */,
   3.189  				4354FF641D6EDF300033069C /* sync_impl.c */,
   3.190  				646C414C1D510D8800C63EFF /* baseprotocol.c */,
   3.191  				646C414D1D510D8800C63EFF /* baseprotocol.h */,
   3.192  				646C413E1D510D2C00C63EFF /* sync_actions.c */,
   3.193 -				646C413F1D510D2C00C63EFF /* sync_driver.c */,
   3.194 -				646C41401D510D2C00C63EFF /* sync_fsm.c */,
   3.195 -				646C41411D510D2C00C63EFF /* sync_fsm.h */,
   3.196 -				646C41421D510D2C00C63EFF /* sync_send_actions.c */,
   3.197 -				646C41431D510D2C00C63EFF /* sync.c */,
   3.198 -				646C41441D510D2C00C63EFF /* sync.h */,
   3.199 -				4346F86A1ECB38E700381CBE /* sync_app.h */,
   3.200  				646788871CEB3D120001F54C /* map_asn1.c */,
   3.201  				646788881CEB3D120001F54C /* map_asn1.h */,
   3.202  				430D258A1C9ED75A00B94535 /* blacklist.c */,
   3.203 @@ -609,13 +617,13 @@
   3.204  				646C40F71D510CD800C63EFF /* ber_decoder.h in Headers */,
   3.205  				646C41351D510CD800C63EFF /* UTF8String.h in Headers */,
   3.206  				646C40EC1D510CD800C63EFF /* asn_codecs_prim.h in Headers */,
   3.207 +				438C439B2167582500C7425B /* sync_api.h in Headers */,
   3.208  				646C40EE1D510CD800C63EFF /* asn_internal.h in Headers */,
   3.209  				646C413B1D510CD800C63EFF /* xer_encoder.h in Headers */,
   3.210  				646C40F01D510CD800C63EFF /* asn_SEQUENCE_OF.h in Headers */,
   3.211  				646C40FD1D510CD800C63EFF /* BIT_STRING.h in Headers */,
   3.212  				646C411F1D510CD800C63EFF /* INTEGER.h in Headers */,
   3.213  				646C411D1D510CD800C63EFF /* IdentityList.h in Headers */,
   3.214 -				646C41331D510CD800C63EFF /* Sync-Protocols.h in Headers */,
   3.215  				646C41011D510CD800C63EFF /* constr_CHOICE.h in Headers */,
   3.216  				646C40FB1D510CD800C63EFF /* ber_tlv_tag.h in Headers */,
   3.217  				646C414F1D510D8800C63EFF /* baseprotocol.h in Headers */,
   3.218 @@ -634,16 +642,13 @@
   3.219  				646C41191D510CD800C63EFF /* Hex.h in Headers */,
   3.220  				646C41051D510CD800C63EFF /* constr_SEQUENCE.h in Headers */,
   3.221  				646C41151D510CD800C63EFF /* Hash.h in Headers */,
   3.222 -				646C410F1D510CD800C63EFF /* DeviceGroup-Protocol.h in Headers */,
   3.223  				646C40FF1D510CD800C63EFF /* BOOLEAN.h in Headers */,
   3.224 -				646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */,
   3.225  				64A8268C1B455D9D00EECAF0 /* pEpEngine.h in Headers */,
   3.226  				646C41091D510CD800C63EFF /* constr_TYPE.h in Headers */,
   3.227  				430BCC482015EE800077E998 /* pEp_string.h in Headers */,
   3.228  				646C410D1D510CD800C63EFF /* der_encoder.h in Headers */,
   3.229  				646C41231D510CD800C63EFF /* NativeEnumerated.h in Headers */,
   3.230  				646C41071D510CD800C63EFF /* constr_SET_OF.h in Headers */,
   3.231 -				646C414B1D510D2C00C63EFF /* sync.h in Headers */,
   3.232  				C46EBAEE216E445F0042A6A3 /* base64.h in Headers */,
   3.233  				646C411B1D510CD800C63EFF /* Identity.h in Headers */,
   3.234  				646C412B1D510CD800C63EFF /* per_encoder.h in Headers */,
   3.235 @@ -807,7 +812,7 @@
   3.236  			);
   3.237  			runOnlyForDeploymentPostprocessing = 0;
   3.238  			shellPath = /bin/sh;
   3.239 -			shellScript = "bash -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";
   3.240 +			shellScript = "export LANG=en_US.UTF-8\nmkdir -p \"$BUILT_PRODUCTS_DIR/include\"\n\ncd \"$SRCROOT/..\"\n\nbash -l -c \"gmake -C sync\"\nbash -l -c \"gmake -C asn.1\"\n";
   3.241  		};
   3.242  /* End PBXShellScriptBuildPhase section */
   3.243  
   3.244 @@ -824,10 +829,11 @@
   3.245  			buildActionMask = 2147483647;
   3.246  			files = (
   3.247  				64A826871B455D0800EECAF0 /* stringpair.c in Sources */,
   3.248 -				43E9BC6A1DB51A1E00AD2352 /* GroupUpdate.c in Sources */,
   3.249 +				43F73C0E2166282C00AB4524 /* sync_codec.c in Sources */,
   3.250  				646C41341D510CD800C63EFF /* UTF8String.c in Sources */,
   3.251  				64A826831B455D0800EECAF0 /* platform_unix.c in Sources */,
   3.252  				646C40F81D510CD800C63EFF /* ber_tlv_length.c in Sources */,
   3.253 +				43F73BF2216626E100AB4524 /* Sync_func.c in Sources */,
   3.254  				646C411C1D510CD800C63EFF /* IdentityList.c in Sources */,
   3.255  				646C41301D510CD800C63EFF /* PrintableString.c in Sources */,
   3.256  				64A8267B1B455D0800EECAF0 /* etpan_mime.c in Sources */,
   3.257 @@ -835,52 +841,57 @@
   3.258  				438C43B62167752C00C7425B /* labeled_int_list.c in Sources */,
   3.259  				646C41261D510CD800C63EFF /* OCTET_STRING.c in Sources */,
   3.260  				646C41141D510CD800C63EFF /* Hash.c in Sources */,
   3.261 -				646C410E1D510CD800C63EFF /* DeviceGroup-Protocol.c in Sources */,
   3.262 +				43F73BF02166269200AB4524 /* PString.c in Sources */,
   3.263  				64A826861B455D0800EECAF0 /* stringlist.c in Sources */,
   3.264  				4354FF651D6EDF300033069C /* sync_impl.c in Sources */,
   3.265  				64A8267E1B455D0800EECAF0 /* message_api.c in Sources */,
   3.266 -				43E9BC7F1DB6720E00AD2352 /* UpdateRequest.c in Sources */,
   3.267  				646C41361D510CD800C63EFF /* Version.c in Sources */,
   3.268  				646C41081D510CD800C63EFF /* constr_TYPE.c in Sources */,
   3.269  				646C40FE1D510CD800C63EFF /* BOOLEAN.c in Sources */,
   3.270  				646C41001D510CD800C63EFF /* constr_CHOICE.c in Sources */,
   3.271  				646C41121D510CD800C63EFF /* HandshakeRequest.c in Sources */,
   3.272 -				646C41471D510D2C00C63EFF /* sync_fsm.c in Sources */,
   3.273  				64A826821B455D0800EECAF0 /* pgp_netpgp.c in Sources */,
   3.274  				646C41101D510CD800C63EFF /* GroupKeys.c in Sources */,
   3.275  				646C40EF1D510CD800C63EFF /* asn_SEQUENCE_OF.c in Sources */,
   3.276  				64A826891B455D0800EECAF0 /* trans_auto.c in Sources */,
   3.277  				646C410C1D510CD800C63EFF /* der_encoder.c in Sources */,
   3.278 +				43F73C112166282C00AB4524 /* sync_api.c in Sources */,
   3.279  				646C41381D510CD800C63EFF /* xer_decoder.c in Sources */,
   3.280 +				43F73BFE216627CC00AB4524 /* KeySync.c in Sources */,
   3.281  				646C41181D510CD800C63EFF /* Hex.c in Sources */,
   3.282  				64A8267D1B455D0800EECAF0 /* keymanagement.c in Sources */,
   3.283 +				43F73C01216627CC00AB4524 /* HandshakeAnswer.c in Sources */,
   3.284  				646C40EB1D510CD800C63EFF /* asn_codecs_prim.c in Sources */,
   3.285  				646C41451D510D2C00C63EFF /* sync_actions.c in Sources */,
   3.286  				646C40F61D510CD800C63EFF /* ber_decoder.c in Sources */,
   3.287  				646C40F11D510CD800C63EFF /* asn_SET_OF.c in Sources */,
   3.288 -				4354FF691D6EE1A70033069C /* NULL.c in Sources */,
   3.289  				646C413A1D510CD800C63EFF /* xer_encoder.c in Sources */,
   3.290 +				43F73BFD216627CC00AB4524 /* TID.c in Sources */,
   3.291  				646C41021D510CD800C63EFF /* constr_SEQUENCE_OF.c in Sources */,
   3.292  				646C410A1D510CD800C63EFF /* constraints.c in Sources */,
   3.293 -				646C41461D510D2C00C63EFF /* sync_driver.c in Sources */,
   3.294  				64A8267C1B455D0800EECAF0 /* identity_list.c in Sources */,
   3.295  				646C40FC1D510CD800C63EFF /* BIT_STRING.c in Sources */,
   3.296  				646C40F41D510CD800C63EFF /* Beacon.c in Sources */,
   3.297 +				43F73C0D2166282C00AB4524 /* key_reset.c in Sources */,
   3.298 +				43F73BFC216627CC00AB4524 /* CommitAccept.c in Sources */,
   3.299  				646C411E1D510CD800C63EFF /* INTEGER.c in Sources */,
   3.300  				646C413C1D510CD800C63EFF /* xer_support.c in Sources */,
   3.301  				64A8268A1B455D0800EECAF0 /* transport.c in Sources */,
   3.302 -				646C41491D510D2C00C63EFF /* sync_send_actions.c in Sources */,
   3.303  				646C41201D510CD800C63EFF /* ISO639-1.c in Sources */,
   3.304 -				646C414A1D510D2C00C63EFF /* sync.c in Sources */,
   3.305  				64A826791B455D0800EECAF0 /* cryptotech.c in Sources */,
   3.306 -				43BA0F461D7964750059172F /* asn1_helper.c in Sources */,
   3.307 +				43F73C0F2166282C00AB4524 /* KeySync_fsm.c in Sources */,
   3.308  				646C412A1D510CD800C63EFF /* per_encoder.c in Sources */,
   3.309  				646C412E1D510CD800C63EFF /* per_support.c in Sources */,
   3.310 +				43F73C0C2166282C00AB4524 /* Sync_event.c in Sources */,
   3.311  				64A826781B455D0800EECAF0 /* bloblist.c in Sources */,
   3.312  				C46EBAED216E445F0042A6A3 /* base64.c in Sources */,
   3.313  				430BCC492015EE800077E998 /* pEp_string.c in Sources */,
   3.314 +				43F73C00216627CC00AB4524 /* Rollback.c in Sources */,
   3.315  				646C41041D510CD800C63EFF /* constr_SEQUENCE.c in Sources */,
   3.316 +				43F73C14216628CA00AB4524 /* Sync.c in Sources */,
   3.317 +				43F73C0B2166282C00AB4524 /* openpgp_compat.c in Sources */,
   3.318  				43370833203C075A004E6547 /* sqlite3.c in Sources */,
   3.319 +				43F73C02216627CC00AB4524 /* CommitReject.c in Sources */,
   3.320  				64A826881B455D0800EECAF0 /* timestamp.c in Sources */,
   3.321  				646C41221D510CD800C63EFF /* NativeEnumerated.c in Sources */,
   3.322  				43F6921D1F164A47009418F5 /* resource_id.c in Sources */,
   3.323 @@ -890,13 +901,14 @@
   3.324  				646C40FA1D510CD800C63EFF /* ber_tlv_tag.c in Sources */,
   3.325  				646C41241D510CD800C63EFF /* NativeInteger.c in Sources */,
   3.326  				646C41061D510CD800C63EFF /* constr_SET_OF.c in Sources */,
   3.327 +				43F73C122166282C00AB4524 /* growing_buf.c in Sources */,
   3.328  				646C412C1D510CD800C63EFF /* per_opentype.c in Sources */,
   3.329  				646C41281D510CD800C63EFF /* per_decoder.c in Sources */,
   3.330  				64A826801B455D0800EECAF0 /* mime.c in Sources */,
   3.331  				64A8267F1B455D0800EECAF0 /* message.c in Sources */,
   3.332  				646C411A1D510CD800C63EFF /* Identity.c in Sources */,
   3.333 +				43F73BFF216627CC00AB4524 /* GroupKeysAndClose.c in Sources */,
   3.334  				64A826811B455D0800EECAF0 /* pEpEngine.c in Sources */,
   3.335 -				646C41321D510CD800C63EFF /* Sync-Protocols.c in Sources */,
   3.336  			);
   3.337  			runOnlyForDeploymentPostprocessing = 0;
   3.338  		};
   3.339 @@ -990,7 +1002,7 @@
   3.340  					"$(SRCROOT)/../../OpenSSL-for-iPhone/include",
   3.341  					"$(SRCROOT)/../asn.1/",
   3.342  				);
   3.343 -				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
   3.344 +				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
   3.345  				MTL_ENABLE_DEBUG_INFO = YES;
   3.346  				ONLY_ACTIVE_ARCH = YES;
   3.347  				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
   3.348 @@ -1047,7 +1059,7 @@
   3.349  					"$(SRCROOT)/../../OpenSSL-for-iPhone/include",
   3.350  					"$(SRCROOT)/../asn.1/",
   3.351  				);
   3.352 -				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
   3.353 +				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
   3.354  				MTL_ENABLE_DEBUG_INFO = NO;
   3.355  				ONLY_ACTIVE_ARCH = NO;
   3.356  				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/default.conf	Mon Apr 01 20:58:40 2019 +0200
     4.3 @@ -0,0 +1,280 @@
     4.4 +# Copyright 2017, pEp Foundation
     4.5 +# This file is part of pEpEngine
     4.6 +# This file may be used under the terms of the GNU General Public License version 3
     4.7 +# see LICENSE.txt
     4.8 +
     4.9 +# See `doc/build-<your platform>.md` for documentation on how to build, and customize your build.
    4.10 +
    4.11 +# This file sets all the make variables that allow you to customize a build.
    4.12 +# There are 4 ways in which you can customize your build:
    4.13 +# 1) Edit the variable assignments in this file (this is a tracked file, so your repository will be dirty)
    4.14 +# 2) Edit the variable assignments in `Makefile.conf` (which is a tracked file, so your repository will be dirty)
    4.15 +# 3) Create `local.conf` and fill it with variable assignments.
    4.16 +# 4) Set the environment variable `BUILD_CONFIG` to an absolute path.
    4.17 +#    The variable assignments found in the make file at the path indicated by `BUILD_CONFIG` will be evaluated.
    4.18 +# Customization options are applied in the order given above. Later variable assignments take precedence over earlier ones.
    4.19 +# It is possible to use multiple variants simultaniously.
    4.20 +# If nothing is changed according to these 4 methods, a default configuration for your platform (specified below) will be used for the build.
    4.21 +
    4.22 +
    4.23 +######### Header #########
    4.24 +HERE:=$(dir $(lastword $(MAKEFILE_LIST)))
    4.25 +
    4.26 +
    4.27 +######### General #########
    4.28 +# To use (only) system libraries, set all the *_INC and *_LIB variables to the empty string.
    4.29 +# All the *_INC and *_LIB variables are command line flags, not paths.
    4.30 +# Thus, all *_INC variables' values must start with "-I", and all *_LIB variables' values must start with "-L".
    4.31 +
    4.32 +BUILD_ON:=$(shell uname)
    4.33 +
    4.34 +# This variable specifies the platform that the engine should be cross-compiled for.
    4.35 +BUILD_FOR=$(BUILD_ON)
    4.36 +
    4.37 +# Cross-compiling is currently not supported.
    4.38 +# Maybe you can hack something with `local.conf`.
    4.39 +ifneq ($(BUILD_ON),$(BUILD_FOR))
    4.40 +    $(error I don't know how to build for $(BUILD_FOR) on $(BUILD_ON).)
    4.41 +endif
    4.42 +
    4.43 +# Installation path prefix for libraries and binaries, except for system.db
    4.44 +PREFIX=$(HOME)
    4.45 +
    4.46 +# Installation path for system.db
    4.47 +SYSTEM_DB=/usr/local/share/pEp/system.db
    4.48 +
    4.49 +# Filename of the pEpEngine library
    4.50 +ifeq ($(BUILD_FOR),Linux)
    4.51 +    TARGET=libpEpEngine.so
    4.52 +else ifeq ($(BUILD_FOR),Darwin)
    4.53 +    TARGET=libpEpEngine.dylib
    4.54 +endif
    4.55 +
    4.56 +# If empty, create a release build.
    4.57 +# Otherwise, create a debug build.
    4.58 +# This variable is ineffective in your local.conf file.
    4.59 +DEBUG=placeholder
    4.60 +
    4.61 +# If empty, suppress compiler warnings.
    4.62 +# Otherwise, print warnings.
    4.63 +# This variable is ineffective in your local.conf file.
    4.64 +WARN=placeholder
    4.65 +
    4.66 +
    4.67 +######### C and C++ #########
    4.68 +TARGET_ARCH=
    4.69 +# The following two variables will be appended to.
    4.70 +# You can thus not set them to a fixed value here.
    4.71 +ifeq ($(BUILD_FOR),Linux)
    4.72 +    LDFLAGS=
    4.73 +else ifeq ($(BUILD_FOR),Darwin)
    4.74 +    # "-bind_at_load" helps find symbol resolution errors faster
    4.75 +    LDFLAGS=-bind_at_load
    4.76 +endif
    4.77 +
    4.78 +LDLIBS=
    4.79 +
    4.80 +
    4.81 +######### C #########
    4.82 +ifeq ($(BUILD_FOR),Linux)
    4.83 +    CC=gcc -std=c99 -pthread
    4.84 +else ifeq ($(BUILD_FOR),Darwin)
    4.85 +    # clang issues a warning when "-pthread" is used for linking.
    4.86 +    # So, include it in CFLAGS, and not in CC
    4.87 +    CC=clang -std=c99
    4.88 +endif
    4.89 +
    4.90 +ifeq ($(BUILD_FOR),Linux)
    4.91 +    CFLAGS=-fPIC -fstrict-aliasing -fdiagnostics-color=always
    4.92 +else ifeq ($(BUILD_FOR),Darwin)
    4.93 +    CFLAGS=-pthread -fPIC -fstrict-aliasing -fcolor-diagnostics
    4.94 +endif
    4.95 +
    4.96 +CPPFLAGS=
    4.97 +
    4.98 +# The flag -DNDEBUG will always be removed from CFLAGS for compiling tests.
    4.99 +# The tests do not work properly, if compiled with -DNDEBUG
   4.100 +ifeq ($(BUILD_FOR),Linux)
   4.101 +    ifdef WARN
   4.102 +        CFLAGS+= -Wall -pedantic -Wstrict-aliasing=3
   4.103 +    else
   4.104 +        CFLAGS+= -w
   4.105 +    endif
   4.106 +    ifdef DEBUG
   4.107 +        CFLAGS+= -g -ggdb -DDEBUG_ERRORSTACK
   4.108 +    else
   4.109 +        CFLAGS+= -O3 -DNDEBUG
   4.110 +    endif
   4.111 +else ifeq ($(BUILD_FOR),Darwin)
   4.112 +    ifdef WARN
   4.113 +        # FIXME Remove 'no-extended-offsetof' after ENGINE-236 is closed.
   4.114 +        CFLAGS+= -Wall -pedantic -Wno-extended-offsetof
   4.115 +    else
   4.116 +        CFLAGS+= -w
   4.117 +    endif
   4.118 +    ifdef DEBUG
   4.119 +        CFLAGS+= -O0 -g -DDEBUG_ERRORSTACK
   4.120 +    else
   4.121 +        CFLAGS+= -O3 -DNDEBUG
   4.122 +    endif
   4.123 +endif
   4.124 +
   4.125 +# Additional CFLAGS used for compiling ASN1C-generated code
   4.126 +ifeq ($(BUILD_FOR),Linux)
   4.127 +    # The '_DEFAULT_SOURCE' feature test macro is required to suppress the warning
   4.128 +    #   _BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE
   4.129 +    # otherwise printed during the compilation of every asn1c-generated C file.
   4.130 +    # It's a glibc specific warning, only present in few versions around ~2.19.
   4.131 +    # See https://lwn.net/Articles/590381/ for a discussion.
   4.132 +    CFLAGS_GENERATED=-D_DEFAULT_SOURCE
   4.133 +else ifeq ($(BUILD_FOR),Darwin)
   4.134 +    CFLAGS_GENERATED=
   4.135 +endif
   4.136 +
   4.137 +
   4.138 +######### C++ #########
   4.139 +ifeq ($(BUILD_FOR),Linux)
   4.140 +    CXX=g++ -std=gnu++11 -pthread
   4.141 +else ifeq ($(BUILD_FOR),Darwin)
   4.142 +    # clang issues a warning when "-pthread" is used for linking. So, include it in CXXFLAGS, and not in CXX
   4.143 +    CXX=clang -std=c++11
   4.144 +endif
   4.145 +
   4.146 +# The flag -DNDEBUG will always be removed from CXXFLAGS for compiling tests.
   4.147 +# The tests do not work properly, if compiled with -DNDEBUG
   4.148 +ifeq ($(BUILD_FOR),Linux)
   4.149 +    CXXFLAGS=-fdiagnostics-color=always -I../src -I../asn.1 $(ETPAN_INC)
   4.150 +    ifdef WARN
   4.151 +        CXXFLAGS+=
   4.152 +    else
   4.153 +        CXXFLAGS+= -w
   4.154 +    endif
   4.155 +    ifdef DEBUG
   4.156 +        CXXFLAGS+= -g -ggdb
   4.157 +    else
   4.158 +        CXXFLAGS+= -O3 -DNDEBUG
   4.159 +    endif
   4.160 +else ifeq ($(BUILD_FOR),Darwin)
   4.161 +    CXXFLAGS=-pthread -fcolor-diagnostics -I../src -I../asn.1 $(ETPAN_INC)
   4.162 +    ifdef WARN
   4.163 +        CXXFLAGS+=
   4.164 +    else
   4.165 +        CXXFLAGS+= -w
   4.166 +    endif
   4.167 +    ifdef DEBUG
   4.168 +        CXXFLAGS+= -O0 -g
   4.169 +    else
   4.170 +        CXXFLAGS+= -O3 -DNDEBUG
   4.171 +    endif
   4.172 +endif
   4.173 +
   4.174 +
   4.175 +######### YML2 #########
   4.176 +YML2_PATH=$(HOME)/yml2
   4.177 +
   4.178 +YML2_PROC=$(YML2_PATH)/yml2proc
   4.179 +
   4.180 +YML2_OPTS=--encoding=utf8
   4.181 +
   4.182 +
   4.183 +######### asn1c #########
   4.184 +# asn1c binary
   4.185 +ASN1C=asn1c
   4.186 +
   4.187 +# asn1c include search flag
   4.188 +ASN1C_INC=-I$(PREFIX)/include
   4.189 +
   4.190 +
   4.191 +######### libetpan #########
   4.192 +# libetpan library search flag
   4.193 +ETPAN_LIB=-L$(PREFIX)/lib
   4.194 +
   4.195 +# libetpan include search flag
   4.196 +ETPAN_INC=-I$(PREFIX)/include
   4.197 +
   4.198 +
   4.199 +######### sqlite3 #########
   4.200 +# If empty (or undefined), compile sqlite3 from the sources shipped with the pEp distribution.
   4.201 +# Otherwise, use an sqlite3 implementation found in the OS's include/library paths.
   4.202 +SQLITE3_FROM_OS=placeholder
   4.203 +
   4.204 +
   4.205 +######### OpenPGP #########
   4.206 +# Path of GPG binary
   4.207 +# gpgconf is not available for old version of GPG, for example GPG 2.0.30. Override this variable, if you compile the engine for such an old version.
   4.208 +GPG_CMD:=$(shell gpgconf --list-components | awk -F: '/^gpg:/ { print $$3; exit 0; }')
   4.209 +
   4.210 +# Selects OpenPGP implementation. must be either `GPG` or `NETPGP` or `SEQUOIA`
   4.211 +OPENPGP=GPG
   4.212 +
   4.213 +# Path of libGPGME binary
   4.214 +ifeq ($(BUILD_FOR),Linux)
   4.215 +    LIBGPGME=libgpgme.so.11
   4.216 +else ifeq ($(BUILD_FOR),Darwin)
   4.217 +    LIBGPGME=libgpgme.11.dylib
   4.218 +endif
   4.219 +
   4.220 +# libGPGME library search flag
   4.221 +ifeq ($(BUILD_FOR),Linux)
   4.222 +    GPGME_LIB=
   4.223 +else ifeq ($(BUILD_FOR),Darwin)
   4.224 +    GPGME_LIB=-L$(HOME)/lib
   4.225 +endif
   4.226 +
   4.227 +# libGPGME include search flag
   4.228 +ifeq ($(BUILD_FOR),Linux)
   4.229 +    GPGME_INC=
   4.230 +else ifeq ($(BUILD_FOR),Darwin)
   4.231 +    GPGME_INC=-I$(HOME)/include
   4.232 +endif
   4.233 +
   4.234 +# NETPGP library search flag
   4.235 +NETPGP_LIB=
   4.236 +#NETPGP_LIB=-L$(PREFIX)/lib
   4.237 +
   4.238 +# libGPGME include search flag
   4.239 +NETPGP_INC=
   4.240 +#NETPGP_INC=-I$(PREFIX)/include
   4.241 +
   4.242 +SEQUOIA_CFLAGS=$(shell pkg-config --cflags-only-other sequoia-openpgp)
   4.243 +SEQUOIA_LDFLAGS=$(shell pkg-config --libs-only-l --libs-only-other sequoia-openpgp)
   4.244 +SEQUOIA_LIB=$(shell pkg-config --libs-only-L sequoia-openpgp)
   4.245 +SEQUOIA_INC=$(shell pkg-config --cflags-only-I sequoia-openpgp)
   4.246 +
   4.247 +
   4.248 +######### OpenPGP #########
   4.249 +# CppUnit library search flag
   4.250 +CPPUNIT_LIB=
   4.251 +#CPPUNIT_LIB=-L$(HOME)/local/lib
   4.252 +
   4.253 +# CppUnit include search flag
   4.254 +CPPUNIT_INC=
   4.255 +#CPPUNIT_INC=-I$(HOME)/local/inc
   4.256 +
   4.257 +
   4.258 +######### Engine internals #########
   4.259 +# C macros (not environment variables) that can be overridden:
   4.260 +# DEFAULT_KEYSERVER - string with default keyserver
   4.261 +# CRASHDUMP_DEFAULT_LINES - number of log lines to deliver for crashdumps
   4.262 +# Example:
   4.263 +#    EXTRA_MACROS=-DDEFAULT_KEYSERVER=\"default-server.org\" -DCRASHDUMP_DEFAULT_LINES=23
   4.264 +EXTRA_MACROS=
   4.265 +
   4.266 +
   4.267 +######### Misc #########
   4.268 +# FIXME Maybe include these variables here.
   4.269 +# Check how they are used throughout the project before setting them here
   4.270 +#LLDB_BIN
   4.271 +
   4.272 +
   4.273 +######### Footer #########
   4.274 +include $(HERE)/Makefile.conf
   4.275 +
   4.276 +-include $(HERE)/local.conf
   4.277 +
   4.278 +ifdef BUILD_CONFIG
   4.279 +    include $(BUILD_CONFIG)
   4.280 +endif
   4.281 +
   4.282 +# YML_PATH is needed in the environment of every call to a program of the YML2 distribution
   4.283 +export YML_PATH=$(YML2_PATH)
     5.1 --- a/src/Makefile	Thu Feb 07 16:02:11 2019 +0100
     5.2 +++ b/src/Makefile	Mon Apr 01 20:58:40 2019 +0200
     5.3 @@ -80,7 +80,7 @@
     5.4  objects: $(ALL_OBJECTS)
     5.5  
     5.6  libpEpEngine.a: $(ALL_OBJECTS)
     5.7 -	ar -rc $@ $^
     5.8 +	$(AR) -rc $@ $^
     5.9  
    5.10  .PHONY: clean
    5.11  clean:
     6.1 --- a/src/baseprotocol.c	Thu Feb 07 16:02:11 2019 +0100
     6.2 +++ b/src/baseprotocol.c	Mon Apr 01 20:58:40 2019 +0200
     6.3 @@ -9,7 +9,8 @@
     6.4          message *msg,
     6.5          char *payload,
     6.6          size_t size,
     6.7 -        char *fpr
     6.8 +        const char *fpr,
     6.9 +        stringlist_t **keys
    6.10      )
    6.11  {
    6.12      PEP_STATUS status = PEP_STATUS_OK;
    6.13 @@ -39,12 +40,36 @@
    6.14          assert(sign && sign_size);
    6.15  
    6.16          bl = bloblist_add(bl, sign, sign_size,
    6.17 -                "application/pEp.sign", "ignore_this_attachment.pEp");
    6.18 +                "application/pEp.sign", "electronic_signature.asc");
    6.19          if (!bl)
    6.20              goto enomem;
    6.21      }
    6.22  
    6.23 -    return PEP_STATUS_OK;
    6.24 +    if (keys) {
    6.25 +        size_t size = 1;
    6.26 +        for (stringlist_t *sl = *keys; sl && sl->value; sl = sl->next) {
    6.27 +            size += strlen(sl->value);
    6.28 +        }
    6.29 +
    6.30 +        char *_keys = calloc(1, size);
    6.31 +        if (!_keys)
    6.32 +            goto enomem;
    6.33 +
    6.34 +        char *_k = _keys;
    6.35 +        for (stringlist_t *sl = *keys; sl && sl->value; sl = sl->next) {
    6.36 +            strcpy(_k, sl->value);
    6.37 +            _k += strlen(sl->value);
    6.38 +        }
    6.39 +
    6.40 +        bl = bloblist_add(bl, _keys, size, "application/pgp-keys", "keys.asc");
    6.41 +        if (!bl)
    6.42 +            status = PEP_OUT_OF_MEMORY;
    6.43 +
    6.44 +        free_stringlist(*keys);
    6.45 +        *keys = NULL;
    6.46 +    }
    6.47 +
    6.48 +    return status;
    6.49  
    6.50  enomem:
    6.51      status = PEP_OUT_OF_MEMORY;
    6.52 @@ -59,7 +84,8 @@
    6.53          const pEp_identity *partner,
    6.54          char *payload,
    6.55          size_t size,
    6.56 -        char *fpr,
    6.57 +        const char *fpr,
    6.58 +        stringlist_t **keys,
    6.59          message **result
    6.60      )
    6.61  {
    6.62 @@ -101,7 +127,7 @@
    6.63      if (!msg->longmsg)
    6.64          goto enomem;
    6.65  
    6.66 -    status = base_decorate_message(session, msg, payload, size, fpr);
    6.67 +    status = base_decorate_message(session, msg, payload, size, fpr, keys);
    6.68      if (status == PEP_STATUS_OK)
    6.69          *result = msg;
    6.70      return status;
     7.1 --- a/src/baseprotocol.h	Thu Feb 07 16:02:11 2019 +0100
     7.2 +++ b/src/baseprotocol.h	Mon Apr 01 20:58:40 2019 +0200
     7.3 @@ -31,7 +31,8 @@
     7.4          message *msg,
     7.5          char *payload,
     7.6          size_t size,
     7.7 -        char *fpr
     7.8 +        const char *fpr,
     7.9 +        stringlist_t **keys
    7.10      );
    7.11  
    7.12  
    7.13 @@ -59,7 +60,8 @@
    7.14          const pEp_identity *partner,
    7.15          char *payload,
    7.16          size_t size,
    7.17 -        char *fpr,
    7.18 +        const char *fpr,
    7.19 +        stringlist_t **keys,
    7.20          message **result
    7.21      );
    7.22  
     8.1 --- a/src/key_reset.c	Thu Feb 07 16:02:11 2019 +0100
     8.2 +++ b/src/key_reset.c	Mon Apr 01 20:58:40 2019 +0200
     8.3 @@ -394,7 +394,7 @@
     8.4                  //
     8.5                  // if (!EMPTYSTR(ident->fpr))
     8.6                  //     fpr_copy = strdup(ident->fpr);
     8.7 -                status = _myself(session, ident, false, true);
     8.8 +                status = _myself(session, ident, false, true, true);
     8.9                  if (status == PEP_STATUS_OK && ident->fpr)
    8.10                      fpr_copy = strdup(ident->fpr);
    8.11                  else {
     9.1 --- a/src/keymanagement.c	Thu Feb 07 16:02:11 2019 +0100
     9.2 +++ b/src/keymanagement.c	Mon Apr 01 20:58:40 2019 +0200
     9.3 @@ -576,9 +576,44 @@
     9.4      char* default_own_id = NULL;
     9.5      status = get_default_own_userid(session, &default_own_id);    
     9.6  
     9.7 -    // Is this me, temporary or not? If so, BAIL.
     9.8 -    if (identity->me || 
     9.9 -       (default_own_id && identity->user_id && (strcmp(default_own_id, identity->user_id) == 0))) 
    9.10 +    bool is_own_user = identity->me;
    9.11 +
    9.12 +    // Is this me, temporary or not? If so, BAIL.    
    9.13 +    if (!is_own_user) {
    9.14 +        if (default_own_id) {
    9.15 +            if (!EMPTYSTR(identity->user_id)) {
    9.16 +                if (strcmp(default_own_id, identity->user_id) == 0) {
    9.17 +                    is_own_user = true;
    9.18 +                }
    9.19 +                else {
    9.20 +                    char* alias = NULL;
    9.21 +                    if (get_userid_alias_default(session, identity->user_id, &alias) == PEP_STATUS_OK) {
    9.22 +                        if (alias && strcmp(default_own_id, alias) == 0)
    9.23 +                            is_own_user = true;
    9.24 +                        free(alias);    
    9.25 +                    }
    9.26 +                }
    9.27 +            }
    9.28 +            else {
    9.29 +                // Check if own address. For now, this is a special case;
    9.30 +                // we try to require apps to send in user_ids, but must prevent
    9.31 +                // writes to an own identity from within THIS function
    9.32 +                // NOTE: These semantics MAY CHANGE.
    9.33 +                bool _own_addr = false;
    9.34 +                is_own_address(session, identity->address, &_own_addr);
    9.35 +                
    9.36 +                // N.B. KB: I would prefer consistent semantics here - that is to say,
    9.37 +                // we also set is_own_user here and force PEP_ILLEGAL_VALUE                
    9.38 +                if (_own_addr) {
    9.39 +                    free(identity->user_id);
    9.40 +                    identity->user_id = strdup(default_own_id);
    9.41 +                    return _myself(session, identity, false, false, true);
    9.42 +                }    
    9.43 +            }
    9.44 +        }
    9.45 +        // Otherwise, we don't even HAVE an own user yet, so we're ok.
    9.46 +    }    
    9.47 +    if (is_own_user)
    9.48      {
    9.49          free(default_own_id);
    9.50          return PEP_ILLEGAL_VALUE;
    9.51 @@ -994,7 +1029,11 @@
    9.52      return status;
    9.53  }
    9.54  
    9.55 -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags)
    9.56 +PEP_STATUS _myself(PEP_SESSION session, 
    9.57 +                   pEp_identity * identity, 
    9.58 +                   bool do_keygen, 
    9.59 +                   bool ignore_flags,
    9.60 +                   bool read_only)
    9.61  {
    9.62  
    9.63      PEP_STATUS status;
    9.64 @@ -1016,18 +1055,24 @@
    9.65      status = get_default_own_userid(session, &default_own_id);
    9.66  
    9.67      // Deal with non-default user_ids.
    9.68 +    // FIXME: if non-default and read-only, reject totally?
    9.69      if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) {
    9.70 -        
    9.71 -        status = set_userid_alias(session, default_own_id, identity->user_id);
    9.72 -        // Do we want this to be fatal? For now, we'll do it...
    9.73 -        if (status != PEP_STATUS_OK)
    9.74 -            goto pEp_free;
    9.75 -            
    9.76 -        free(identity->user_id);
    9.77 -        identity->user_id = strdup(default_own_id);
    9.78 -        if (identity->user_id == NULL) {
    9.79 -            status = PEP_OUT_OF_MEMORY;
    9.80 -            goto pEp_free;
    9.81 +        if (read_only) {
    9.82 +            free(identity->user_id);
    9.83 +            identity->user_id = strdup(default_own_id);
    9.84 +        }
    9.85 +        else {
    9.86 +            status = set_userid_alias(session, default_own_id, identity->user_id);
    9.87 +            // Do we want this to be fatal? For now, we'll do it...
    9.88 +            if (status != PEP_STATUS_OK)
    9.89 +                goto pEp_free;
    9.90 +                
    9.91 +            free(identity->user_id);
    9.92 +            identity->user_id = strdup(default_own_id);
    9.93 +            if (identity->user_id == NULL) {
    9.94 +                status = PEP_OUT_OF_MEMORY;
    9.95 +                goto pEp_free;
    9.96 +            }
    9.97          }
    9.98      }
    9.99  
   9.100 @@ -1060,7 +1105,7 @@
   9.101      // Set usernames - priority is input username > stored name > address
   9.102      // If there's an input username, we always patch the username with that
   9.103      // input.
   9.104 -    if (EMPTYSTR(identity->username)) {
   9.105 +    if (EMPTYSTR(identity->username) || read_only) {
   9.106          bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username));
   9.107          char* uname = (stored_uname ? stored_identity->username : identity->address);
   9.108          free(identity->username);
   9.109 @@ -1079,41 +1124,45 @@
   9.110      }
   9.111  
   9.112      // check stored identity
   9.113 -    if (stored_identity && !EMPTYSTR(stored_identity->fpr)) {
   9.114 -        // Fall back / retrieve
   9.115 -        status = validate_fpr(session, stored_identity, false, true);
   9.116 -        if (status == PEP_OUT_OF_MEMORY)
   9.117 -            goto pEp_free;
   9.118 -        if (status == PEP_STATUS_OK) {
   9.119 -            if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
   9.120 -                identity->fpr = strdup(stored_identity->fpr);
   9.121 -                assert(identity->fpr);
   9.122 -                if (!identity->fpr) {
   9.123 -                    status = PEP_OUT_OF_MEMORY;
   9.124 -                    goto pEp_free;
   9.125 -                }
   9.126 -                valid_key_found = true;            
   9.127 -            }
   9.128 -            else {
   9.129 -                bool revoked = false;
   9.130 -                status = key_revoked(session, stored_identity->fpr, &revoked);
   9.131 -                if (status)
   9.132 -                    goto pEp_free;
   9.133 -                if (revoked) {
   9.134 -                    revoked_fpr = strdup(stored_identity->fpr);
   9.135 -                    assert(revoked_fpr);
   9.136 -                    if (!revoked_fpr) {
   9.137 +    if (stored_identity) {
   9.138 +        if (!EMPTYSTR(stored_identity->fpr)) {
   9.139 +            // Fall back / retrieve
   9.140 +            status = validate_fpr(session, stored_identity, false, true);
   9.141 +            if (status == PEP_OUT_OF_MEMORY)
   9.142 +                goto pEp_free;
   9.143 +            if (status == PEP_STATUS_OK) {
   9.144 +                if (stored_identity->comm_type >= PEP_ct_strong_but_unconfirmed) {
   9.145 +                    identity->fpr = strdup(stored_identity->fpr);
   9.146 +                    assert(identity->fpr);
   9.147 +                    if (!identity->fpr) {
   9.148                          status = PEP_OUT_OF_MEMORY;
   9.149                          goto pEp_free;
   9.150                      }
   9.151 +                    valid_key_found = true;            
   9.152 +                }
   9.153 +                else {
   9.154 +                    bool revoked = false;
   9.155 +                    status = key_revoked(session, stored_identity->fpr, &revoked);
   9.156 +                    if (status)
   9.157 +                        goto pEp_free;
   9.158 +                    if (revoked) {
   9.159 +                        revoked_fpr = strdup(stored_identity->fpr);
   9.160 +                        assert(revoked_fpr);
   9.161 +                        if (!revoked_fpr) {
   9.162 +                            status = PEP_OUT_OF_MEMORY;
   9.163 +                            goto pEp_free;
   9.164 +                        }
   9.165 +                    }
   9.166                  }
   9.167              }
   9.168          }
   9.169 +        // reconcile language, flags
   9.170 +        transfer_ident_lang_and_flags(identity, stored_identity);
   9.171      }
   9.172      
   9.173      // Nothing left to do but generate a key
   9.174      if (!valid_key_found) {
   9.175 -        if (!do_keygen)
   9.176 +        if (!do_keygen || read_only)
   9.177              status = PEP_GET_KEY_FAILED;
   9.178          else {
   9.179  // /            DEBUG_LOG("Generating key pair", "debug", identity->address);
   9.180 @@ -1151,12 +1200,14 @@
   9.181      
   9.182      // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
   9.183      // it's NOT ok
   9.184 -    PEP_STATUS set_id_status = set_identity(session, identity);
   9.185 -    if (set_id_status == PEP_STATUS_OK)
   9.186 -        set_id_status = set_as_pEp_user(session, identity);
   9.187 +    if (!read_only) {
   9.188 +        PEP_STATUS set_id_status = set_identity(session, identity);
   9.189 +        if (set_id_status == PEP_STATUS_OK)
   9.190 +            set_id_status = set_as_pEp_user(session, identity);
   9.191  
   9.192 -    status = (status == PEP_STATUS_OK ? set_id_status : status);
   9.193 -
   9.194 +        status = (status == PEP_STATUS_OK ? set_id_status : status);
   9.195 +    }
   9.196 +    
   9.197  pEp_free:    
   9.198      free(default_own_id);
   9.199      free(revoked_fpr);                     
   9.200 @@ -1166,7 +1217,7 @@
   9.201  
   9.202  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
   9.203  {
   9.204 -    return _myself(session, identity, true, false);
   9.205 +    return _myself(session, identity, true, false, false);
   9.206  }
   9.207  
   9.208  DYNAMIC_API PEP_STATUS register_examine_function(
   9.209 @@ -1495,7 +1546,6 @@
   9.210          }
   9.211      }    
   9.212  
   9.213 -pEp_free:
   9.214      free(ident_default_fpr);
   9.215      free(cached_fpr);
   9.216      free_identity(tmp_id);
   9.217 @@ -1610,8 +1660,10 @@
   9.218      unsigned int flags = 0;
   9.219      
   9.220      identity_list *_bl = _own_identities;
   9.221 +
   9.222 +    sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
   9.223 +
   9.224      do {
   9.225 -        sqlite3_bind_int(session->own_identities_retrieve, 1, excluded_flags);
   9.226          result = sqlite3_step(session->own_identities_retrieve);
   9.227          switch (result) {
   9.228              case SQLITE_ROW:
   9.229 @@ -1703,8 +1755,9 @@
   9.230      char *fpr = NULL;
   9.231      
   9.232      stringlist_t *_bl = _keylist;
   9.233 -    do {
   9.234 -        sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
   9.235 +    sqlite3_bind_int(session->own_keys_retrieve, 1, excluded_flags);
   9.236 +
   9.237 +    do {        
   9.238          result = sqlite3_step(session->own_keys_retrieve);
   9.239          switch (result) {
   9.240              case SQLITE_ROW:
   9.241 @@ -1770,7 +1823,7 @@
   9.242              EMPTYSTR(me->user_id) || EMPTYSTR(me->username))
   9.243          return PEP_ILLEGAL_VALUE;
   9.244  
   9.245 -    status = _myself(session, me, false, true);
   9.246 +    status = _myself(session, me, false, true, false);
   9.247      // we do not need a valid key but dislike other errors
   9.248      if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE)
   9.249          return status;
   9.250 @@ -1939,6 +1992,7 @@
   9.251          thing = _pgp_thing_next(thing);
   9.252          switch (thing) {
   9.253              case _pgp_fpr:
   9.254 +                // PEP_OWN_USERID is ok here because this is only run on first use!
   9.255                  identity = new_identity(NULL, NULL, PEP_OWN_USERID, NULL);
   9.256                  if (!identity) {
   9.257                      status = PEP_OUT_OF_MEMORY;
    10.1 --- a/src/keymanagement.h	Thu Feb 07 16:02:11 2019 +0100
    10.2 +++ b/src/keymanagement.h	Mon Apr 01 20:58:40 2019 +0200
    10.3 @@ -114,7 +114,11 @@
    10.4  
    10.5  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity);
    10.6  
    10.7 -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
    10.8 +PEP_STATUS _myself(PEP_SESSION session, 
    10.9 +                   pEp_identity * identity, 
   10.10 +                   bool do_keygen, 
   10.11 +                   bool ignore_flags,
   10.12 +                   bool read_only);
   10.13  
   10.14  // retrieve_next_identity() - callback being called by do_keymanagement()
   10.15  //
   10.16 @@ -375,7 +379,7 @@
   10.17                                   stringlist_t** keys);
   10.18  
   10.19  
   10.20 -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
   10.21 +//PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
   10.22  
   10.23  PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr);
   10.24  PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr);
    11.1 --- a/src/message_api.c	Thu Feb 07 16:02:11 2019 +0100
    11.2 +++ b/src/message_api.c	Mon Apr 01 20:58:40 2019 +0200
    11.3 @@ -995,7 +995,7 @@
    11.4                  }                        
    11.5              }
    11.6              else
    11.7 -                status = myself(session, curr_identity);
    11.8 +                status = _myself(session, curr_identity, false, false, true);
    11.9          if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
   11.10              return status;
   11.11          }
   11.12 @@ -1312,7 +1312,8 @@
   11.13      if (!is_me(session, ident))
   11.14          status = update_identity(session, ident);
   11.15      else
   11.16 -        status = myself(session, ident);
   11.17 +        // ???
   11.18 +        status = _myself(session, ident, false, false, true);
   11.19  
   11.20      if (status == PEP_STATUS_OK) {
   11.21          if (ident->comm_type == PEP_ct_compromised)
   11.22 @@ -1366,15 +1367,15 @@
   11.23      return comm_type;
   11.24  }
   11.25  
   11.26 -static void free_bl_entry(bloblist_t *bl)
   11.27 -{
   11.28 -    if (bl) {
   11.29 -        free(bl->value);
   11.30 -        free(bl->mime_type);
   11.31 -        free(bl->filename);
   11.32 -        free(bl);
   11.33 -    }
   11.34 -}
   11.35 +// static void free_bl_entry(bloblist_t *bl)
   11.36 +// {
   11.37 +//     if (bl) {
   11.38 +//         free(bl->value);
   11.39 +//         free(bl->mime_type);
   11.40 +//         free(bl->filename);
   11.41 +//         free(bl);
   11.42 +//     }
   11.43 +// }
   11.44  
   11.45  static bool is_key(const bloblist_t *bl)
   11.46  {
   11.47 @@ -1395,29 +1396,29 @@
   11.48             );
   11.49  }
   11.50  
   11.51 -static void remove_attached_keys(message *msg)
   11.52 -{
   11.53 -    if (msg) {
   11.54 -        bloblist_t *last = NULL;
   11.55 -        for (bloblist_t *bl = msg->attachments; bl && bl->value; ) {
   11.56 -            bloblist_t *next = bl->next;
   11.57 -
   11.58 -            if (is_key(bl)) {
   11.59 -                if (last) {
   11.60 -                    last->next = next;
   11.61 -                }
   11.62 -                else {
   11.63 -                    msg->attachments = next;
   11.64 -                }
   11.65 -                free_bl_entry(bl);
   11.66 -            }
   11.67 -            else {
   11.68 -                last = bl;
   11.69 -            }
   11.70 -            bl = next;
   11.71 -        }
   11.72 -    }
   11.73 -}
   11.74 +// static void remove_attached_keys(message *msg)
   11.75 +// {
   11.76 +//     if (msg) {
   11.77 +//         bloblist_t *last = NULL;
   11.78 +//         for (bloblist_t *bl = msg->attachments; bl && bl->value; ) {
   11.79 +//             bloblist_t *next = bl->next;
   11.80 +// 
   11.81 +//             if (is_key(bl)) {
   11.82 +//                 if (last) {
   11.83 +//                     last->next = next;
   11.84 +//                 }
   11.85 +//                 else {
   11.86 +//                     msg->attachments = next;
   11.87 +//                 }
   11.88 +//                 free_bl_entry(bl);
   11.89 +//             }
   11.90 +//             else {
   11.91 +//                 last = bl;
   11.92 +//             }
   11.93 +//             bl = next;
   11.94 +//         }
   11.95 +//     }
   11.96 +// }
   11.97  
   11.98  static bool compare_first_n_bytes(const char* first, const char* second, size_t n) {
   11.99      int i;
  11.100 @@ -1638,8 +1639,9 @@
  11.101      char* longmsg = NULL;
  11.102      char* shortmsg = NULL;
  11.103      char* msg_wrap_info = NULL;
  11.104 -    separate_short_and_long(src->longmsg, &shortmsg, &msg_wrap_info,
  11.105 -                            &longmsg);
  11.106 +    if (src->longmsg)
  11.107 +        separate_short_and_long(src->longmsg, &shortmsg, &msg_wrap_info,
  11.108 +                                &longmsg);
  11.109      if (longmsg) {                    
  11.110          free(src->longmsg);
  11.111          free(shortmsg);
  11.112 @@ -2977,6 +2979,7 @@
  11.113      return status;
  11.114  }
  11.115  
  11.116 +// FIXME: myself ??????
  11.117  static PEP_STATUS update_sender_to_pEp_trust(
  11.118          PEP_SESSION session, 
  11.119          pEp_identity* sender, 
  11.120 @@ -3281,7 +3284,6 @@
  11.121          identity_list **private_il
  11.122      )
  11.123  {
  11.124 -    
  11.125      assert(session);
  11.126      assert(src);
  11.127      assert(dst);
  11.128 @@ -3307,6 +3309,7 @@
  11.129      stringlist_t *_keylist = NULL;
  11.130      char* signer_fpr = NULL;
  11.131      bool is_pEp_msg = is_a_pEpmessage(src);
  11.132 +    bool myself_read_only = (src->dir == PEP_dir_incoming);
  11.133  
  11.134      // Grab input flags
  11.135      bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
  11.136 @@ -3370,7 +3373,7 @@
  11.137          if (!is_me(session, src->from))
  11.138              status = update_identity(session, src->from);
  11.139          else
  11.140 -            status = myself(session, src->from);
  11.141 +            status = _myself(session, src->from, false, false, myself_read_only);
  11.142          
  11.143          // We absolutely should NOT be bailing here unless it's a serious error
  11.144          if (status == PEP_OUT_OF_MEMORY)
  11.145 @@ -3604,7 +3607,7 @@
  11.146                                                  if (!is_me(session, src->from))
  11.147                                                      update_identity(session, (src->from));
  11.148                                                  else
  11.149 -                                                    myself(session, src->from);
  11.150 +                                                    _myself(session, src->from, false, false, myself_read_only);
  11.151                                              }
  11.152                                              break;        
  11.153                                          }
  11.154 @@ -3822,6 +3825,12 @@
  11.155      return status;
  11.156  }
  11.157  
  11.158 +static bool _own_sync_beacon(PEP_STATUS status, const char *sync_fpr,
  11.159 +        const char *from_fpr) {
  11.160 +    return status == PEP_UNENCRYPTED && sync_fpr && sync_fpr[0] &&
  11.161 +        from_fpr && from_fpr[0] && strcmp(sync_fpr, from_fpr) == 0;
  11.162 +}
  11.163 +
  11.164  DYNAMIC_API PEP_STATUS decrypt_message(
  11.165          PEP_SESSION session,
  11.166          message *src,
  11.167 @@ -3848,22 +3857,15 @@
  11.168  
  11.169      message *msg = *dst ? *dst : src;
  11.170  
  11.171 -    if (session->inject_sync_event && msg && msg->from) {
  11.172 +    if (session->inject_sync_event && msg && msg->from &&
  11.173 +            !(*flags & PEP_decrypt_flag_dont_trigger_sync)) {
  11.174          size_t size;
  11.175          const char *data;
  11.176          char *sync_fpr = NULL;
  11.177 -        status = base_extract_message(session, msg, &size, &data, &sync_fpr);
  11.178 -        if (!status && size && data) {
  11.179 -            pEp_identity *_from = identity_dup(msg->from);
  11.180 -            if (!_from) {
  11.181 -                free_message(*dst);
  11.182 -                *dst = NULL;
  11.183 -                free_stringlist(*keylist);
  11.184 -                *keylist = NULL;
  11.185 -                return PEP_OUT_OF_MEMORY;
  11.186 -            }
  11.187 -            session->sync_state.common.from = _from;
  11.188 -            signal_Sync_message(session, *rating, data, size, sync_fpr);
  11.189 +        PEP_STATUS tmpstatus = base_extract_message(session, msg, &size, &data, &sync_fpr);
  11.190 +        if (!tmpstatus && size && data) {
  11.191 +            if (!_own_sync_beacon(status, sync_fpr, msg->from->fpr))
  11.192 +                signal_Sync_message(session, *rating, data, size, msg->from, sync_fpr);
  11.193          }
  11.194          free(sync_fpr);
  11.195      }
  11.196 @@ -4068,8 +4070,10 @@
  11.197      if (!(session && ident && rating))
  11.198          return PEP_ILLEGAL_VALUE;
  11.199  
  11.200 +    *rating = PEP_rating_undefined;
  11.201 +
  11.202      if (ident->me)
  11.203 -        status = _myself(session, ident, false, true);
  11.204 +        status = _myself(session, ident, false, true, true);
  11.205      else
  11.206          status = update_identity(session, ident);
  11.207  
  11.208 @@ -4418,10 +4422,21 @@
  11.209      // Find own identity corresponding to given account address.
  11.210      // In that case we want default key attached to own identity
  11.211      pEp_identity *stored_identity = NULL;
  11.212 +    
  11.213 +    char* own_id = NULL;
  11.214 +    status = get_default_own_userid(session, &own_id);
  11.215 +
  11.216 +    if (!(status == PEP_STATUS_OK && own_id)) {
  11.217 +        free(own_id);
  11.218 +        return PEP_CANNOT_FIND_IDENTITY;
  11.219 +    }
  11.220 +    
  11.221      status = get_identity(session,
  11.222                            received_by->address,
  11.223 -                          PEP_OWN_USERID,
  11.224 +                          own_id,
  11.225                            &stored_identity);
  11.226 +    free(own_id);
  11.227 +    own_id = NULL;                      
  11.228  
  11.229      if (status != PEP_STATUS_OK) {
  11.230          free_identity(stored_identity);
  11.231 @@ -4467,12 +4482,13 @@
  11.232      if (status != PEP_STATUS_OK)
  11.233          goto pEp_error;
  11.234  
  11.235 +    tmp_msg->dir = PEP_dir_incoming;
  11.236      // MIME decode message delivers only addresses. We need more.
  11.237      if (tmp_msg->from) {
  11.238          if (!is_me(session, tmp_msg->from))
  11.239              status = update_identity(session, (tmp_msg->from));
  11.240          else
  11.241 -            status = myself(session, tmp_msg->from);
  11.242 +            status = _myself(session, tmp_msg->from, false, false, true);
  11.243  
  11.244          if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
  11.245              goto pEp_error;
  11.246 @@ -4790,7 +4806,7 @@
  11.247      if (!is_me(session, msg->from))
  11.248          status = update_identity(session, msg->from);
  11.249      else
  11.250 -        status = myself(session, msg->from);
  11.251 +        status = _myself(session, msg->from, false, false, true);
  11.252  
  11.253      switch (status) {
  11.254          case PEP_KEY_NOT_FOUND:
  11.255 @@ -4849,4 +4865,3 @@
  11.256      free_identity(ident);
  11.257      return status;
  11.258  }
  11.259 -
    12.1 --- a/src/message_api.h	Thu Feb 07 16:02:11 2019 +0100
    12.2 +++ b/src/message_api.h	Mon Apr 01 20:58:40 2019 +0200
    12.3 @@ -270,7 +270,8 @@
    12.4      PEP_decrypt_flag_ignore = 0x4,
    12.5      PEP_decrypt_flag_src_modified = 0x8,
    12.6      // input flags    
    12.7 -    PEP_decrypt_flag_untrusted_server = 0x100
    12.8 +    PEP_decrypt_flag_untrusted_server = 0x100,
    12.9 +    PEP_decrypt_flag_dont_trigger_sync = 0x200,
   12.10  } PEP_decrypt_flags; 
   12.11  
   12.12  typedef unsigned int PEP_decrypt_flags_t;
    13.1 --- a/src/mime.c	Thu Feb 07 16:02:11 2019 +0100
    13.2 +++ b/src/mime.c	Mon Apr 01 20:58:40 2019 +0200
    13.3 @@ -13,6 +13,10 @@
    13.4  #include "etpan_mime.h"
    13.5  #include "wrappers.h"
    13.6  
    13.7 +static PEP_STATUS interpret_MIME(struct mailmime *mime,
    13.8 +                                 message *msg);
    13.9 +
   13.10 +
   13.11  static bool is_whitespace(char c)
   13.12  {
   13.13      switch (c) {
   13.14 @@ -1470,6 +1474,63 @@
   13.15      return PEP_STATUS_OK;
   13.16  }
   13.17  
   13.18 +// ONLY for main part!!!
   13.19 +static PEP_STATUS process_multipart_related(struct mailmime *mime,
   13.20 +                                            message *msg) {
   13.21 +    PEP_STATUS status = PEP_STATUS_OK;
   13.22 +
   13.23 +    assert(mime);
   13.24 +    assert(msg);
   13.25 +
   13.26 +    clist *partlist = mime->mm_data.mm_multipart.mm_mp_list;                                                
   13.27 +
   13.28 +    if (partlist == NULL)
   13.29 +        return PEP_ILLEGAL_VALUE;
   13.30 +
   13.31 +    clistiter *cur = clist_begin(partlist);
   13.32 +    struct mailmime *part = clist_content(cur);
   13.33 +    
   13.34 +    if (part == NULL)
   13.35 +        return PEP_ILLEGAL_VALUE;
   13.36 +
   13.37 +    struct mailmime_content *content = part->mm_content_type;    
   13.38 +    assert(content);
   13.39 +    
   13.40 +    if (content == NULL)
   13.41 +        return PEP_ILLEGAL_VALUE;
   13.42 +
   13.43 +    if (_is_text_part(content, "html")) {
   13.44 +        status = interpret_body(part, &msg->longmsg_formatted,
   13.45 +                NULL);
   13.46 +        if (status)
   13.47 +            return status;
   13.48 +    }
   13.49 +    else {
   13.50 +        // ???
   13.51 +        // This is what we would have done before, so... no
   13.52 +        // worse than the status quo. But FIXME!
   13.53 +        status = interpret_MIME(part, msg);
   13.54 +        if (status)
   13.55 +            return status;
   13.56 +    }
   13.57 +    
   13.58 +    for (cur = clist_next(cur); cur; cur = clist_next(cur)) {
   13.59 +        part = clist_content(cur);
   13.60 +        if (part == NULL)
   13.61 +            return PEP_ILLEGAL_VALUE;
   13.62 +
   13.63 +        content = part->mm_content_type;
   13.64 +        assert(content);
   13.65 +        if (content == NULL)
   13.66 +            return PEP_ILLEGAL_VALUE;
   13.67 +
   13.68 +        status = interpret_MIME(part, msg);
   13.69 +        if (status)
   13.70 +            return status;
   13.71 +    }
   13.72 +    return status;
   13.73 +}
   13.74 +
   13.75  static PEP_STATUS interpret_MIME(
   13.76          struct mailmime *mime,
   13.77          message *msg
   13.78 @@ -1515,6 +1576,12 @@
   13.79                      if (status)
   13.80                          return status;
   13.81                  }
   13.82 +                else if (_is_multipart(content, "related") && 
   13.83 +                    msg->longmsg_formatted == NULL) {
   13.84 +                    status = process_multipart_related(part, msg);
   13.85 +                    if (status)
   13.86 +                        return status;
   13.87 +                }
   13.88                  else /* add as attachment */ {
   13.89                      status = interpret_MIME(part, msg);
   13.90                      if (status)
    14.1 --- a/src/pEpEngine.c	Thu Feb 07 16:02:11 2019 +0100
    14.2 +++ b/src/pEpEngine.c	Mon Apr 01 20:58:40 2019 +0200
    14.3 @@ -79,6 +79,7 @@
    14.4      "select id, word from wordlist where lang = lower(?1) "
    14.5      "and id = ?2 ;";
    14.6  
    14.7 +// FIXME?: problems if we don't have a key for the user - we get nothing
    14.8  static const char *sql_get_identity =  
    14.9      "select fpr, username, comm_type, lang,"
   14.10      "   identity.flags | pgp_keypair.flags,"
   14.11 @@ -162,9 +163,8 @@
   14.12  // Set person, but if already exist, only update.
   14.13  // if main_key_id already set, don't touch.
   14.14  static const char *sql_set_person = 
   14.15 -     "insert into person (id, username, lang, main_key_id, device_group)"
   14.16 -     "  values (?1, ?2, ?3, ?4, "
   14.17 -     "          (select device_group from person where id = ?1)) ;";
   14.18 +     "insert into person (id, username, lang, main_key_id)"
   14.19 +     "  values (?1, ?2, ?3, ?4) ;";
   14.20  
   14.21  static const char *sql_update_person = 
   14.22      "update person "
   14.23 @@ -173,9 +173,7 @@
   14.24      "       main_key_id =  "
   14.25      "           (select coalesce( "
   14.26      "               (select main_key_id from person where id = ?1), " 
   14.27 -    "                upper(replace(?4,' ','')))),"         
   14.28 -    "       device_group = "
   14.29 -    "           (select device_group from person where id = ?1)"
   14.30 +    "                upper(replace(?4,' ',''))))"         
   14.31      "   where id = ?1 ;";
   14.32  
   14.33  // Will cascade.
   14.34 @@ -194,10 +192,6 @@
   14.35      "select count(*) from person "
   14.36      "   where id = ?1 ;";
   14.37  
   14.38 -static const char *sql_set_device_group = 
   14.39 -    "update person set device_group = ?1 "
   14.40 -    "   where id = ?2;";
   14.41 -
   14.42  // This will cascade to identity and trust
   14.43  static const char* sql_replace_userid =
   14.44      "update person set id = ?1 " 
   14.45 @@ -229,10 +223,6 @@
   14.46      "       limit 1) "
   14.47      "where id = ?1 ; ";
   14.48  
   14.49 -static const char *sql_get_device_group = 
   14.50 -    "select device_group from person "
   14.51 -    "where id = ?1;";
   14.52 -
   14.53  static const char *sql_set_pgp_keypair = 
   14.54      "insert or ignore into pgp_keypair (fpr) "
   14.55      "values (upper(replace(?1,' ',''))) ;";
   14.56 @@ -281,7 +271,7 @@
   14.57          
   14.58  static const char *sql_set_identity_flags = 
   14.59      "update identity set flags = "
   14.60 -    "    ((?1 & 255) | (select flags from identity"
   14.61 +    "    ((?1 & 65535) | (select flags from identity"
   14.62      "                    where (case when (address = ?2) then (1)"
   14.63      "                                when (lower(address) = lower(?2)) then (1)"
   14.64      "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   14.65 @@ -297,7 +287,7 @@
   14.66  
   14.67  static const char *sql_unset_identity_flags = 
   14.68      "update identity set flags = "
   14.69 -    "    ( ~(?1 & 255) & (select flags from identity"
   14.70 +    "    ( ~(?1 & 65535) & (select flags from identity"
   14.71      "                    where (case when (address = ?2) then (1)"
   14.72      "                                when (lower(address) = lower(?2)) then (1)"
   14.73      "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   14.74 @@ -389,6 +379,17 @@
   14.75      "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   14.76      "           and identity.is_own = 1"
   14.77      ");";
   14.78 +    
   14.79 +static const char *sql_is_own_address =
   14.80 +    "select count(*) from ("
   14.81 +    "   select address from identity"
   14.82 +    "       where (case when (address = ?1) then (1)"
   14.83 +    "                   when (lower(address) = lower(?1)) then (1)"
   14.84 +    "                   when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   14.85 +    "                   else 0"
   14.86 +    "           end) = 1 "
   14.87 +    "           and identity.is_own = 1"
   14.88 +    ");";
   14.89  
   14.90  static const char *sql_own_identities_retrieve =  
   14.91      "select address, fpr, identity.user_id, username,"
   14.92 @@ -498,6 +499,51 @@
   14.93      return 0;
   14.94  }
   14.95  
   14.96 +// TODO: refactor and generalise these two functions if possible.
   14.97 +static int db_contains_table(PEP_SESSION session, const char* table_name) {
   14.98 +    if (!session || !table_name)
   14.99 +        return -1;
  14.100 +    
  14.101 +    // Table names can't be SQL parameters, so we do it this way.
  14.102 +    
  14.103 +    // these two must be the same number.
  14.104 +    char sql_buf[500];
  14.105 +    const size_t max_q_len = 500;
  14.106 +    
  14.107 +    size_t t_size, q_size;
  14.108 +    
  14.109 +    const char* q1 = "SELECT name FROM sqlite_master WHERE type='table' AND name='{"; // 61
  14.110 +    const char* q2 = "'};";       // 3
  14.111 +    
  14.112 +    q_size = 64;
  14.113 +    t_size = strlen(table_name);
  14.114 +    
  14.115 +    size_t query_len = q_size + t_size + 1;
  14.116 +
  14.117 +    if (query_len > max_q_len)
  14.118 +        return -1;
  14.119 +
  14.120 +    strlcpy(sql_buf, q1, max_q_len);
  14.121 +    strlcat(sql_buf, table_name, max_q_len);
  14.122 +    strlcat(sql_buf, q2, max_q_len);
  14.123 +
  14.124 +    sqlite3_stmt *stmt; 
  14.125 +
  14.126 +    sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
  14.127 +
  14.128 +    int retval = 0;
  14.129 +
  14.130 +    int rc = sqlite3_step(stmt);  
  14.131 +    if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
  14.132 +        retval = 1;
  14.133 +    }
  14.134 +
  14.135 +    sqlite3_finalize(stmt);      
  14.136 +        
  14.137 +    return retval;
  14.138 +        
  14.139 +}
  14.140 +
  14.141  static int table_contains_column(PEP_SESSION session, const char* table_name,
  14.142                                                        const char* col_name) {
  14.143  
  14.144 @@ -680,7 +726,7 @@
  14.145      sqlite3_busy_timeout(_session->system_db, 1000);
  14.146  
  14.147  // increment this when patching DDL
  14.148 -#define _DDL_USER_VERSION "9"
  14.149 +#define _DDL_USER_VERSION "10"
  14.150  
  14.151      if (in_first) {
  14.152  
  14.153 @@ -727,7 +773,7 @@
  14.154                  "       on delete set null,\n"
  14.155                  "   lang text,\n"
  14.156                  "   comment text,\n"
  14.157 -                "   device_group text,\n"
  14.158 +//                "   device_group text,\n"
  14.159                  "   is_pEp_user integer default 0\n"
  14.160                  ");\n"
  14.161                  "create table if not exists identity (\n"
  14.162 @@ -843,14 +889,19 @@
  14.163          assert(int_result == SQLITE_OK);
  14.164  
  14.165          
  14.166 -        // Sometimes the user_version wasn't set correctly. Check to see if this
  14.167 -        // is really necessary...
  14.168 +        // Sometimes the user_version wasn't set correctly. 
  14.169          if (version == 1) {
  14.170              bool version_changed = true;
  14.171 -            if (table_contains_column(_session, "identity", "timestamp") > 0) {
  14.172 +            if (db_contains_table(_session, "social_graph") > 0) {
  14.173 +                if (!table_contains_column(_session, "person", "device_group"))
  14.174 +                    version = 10;
  14.175 +                else
  14.176 +                    version = 9;
  14.177 +            }            
  14.178 +            else if (table_contains_column(_session, "identity", "timestamp") > 0) {
  14.179                  version = 8;
  14.180              }            
  14.181 -            if (table_contains_column(_session, "person", "is_pEp_user") > 0) {
  14.182 +            else if (table_contains_column(_session, "person", "is_pEp_user") > 0) {
  14.183                  version = 7;
  14.184              }            
  14.185              else if (table_contains_column(_session, "identity", "is_own") > 0) {
  14.186 @@ -908,12 +959,13 @@
  14.187              // }
  14.188              
  14.189              if (version < 2) {
  14.190 +                // N.B. addition of device_group column removed in DDL v10
  14.191                  int_result = sqlite3_exec(
  14.192                      _session->db,
  14.193                      "alter table pgp_keypair\n"
  14.194 -                    "   add column flags integer default 0;\n"
  14.195 -                    "alter table person\n"
  14.196 -                    "   add column device_group text;\n",
  14.197 +                    "   add column flags integer default 0;\n",
  14.198 +                    // "alter table person\n"
  14.199 +                    // "   add column device_group text;\n",
  14.200                      NULL,
  14.201                      NULL,
  14.202                      NULL
  14.203 @@ -1100,7 +1152,7 @@
  14.204                      "    CONSTRAINT fk_own_identity\n"
  14.205                      "       FOREIGN KEY(own_address, own_userid)\n" 
  14.206                      "       REFERENCES identity(address, user_id)\n"
  14.207 -                    "       ON DELETE CASCADE ON UPDATE CASCADE,\n"
  14.208 +                    "       ON DELETE CASCADE ON UPDATE CASCADE\n"
  14.209                      ");\n"
  14.210                      "create table if not exists revocation_contact_list (\n"
  14.211                      "   fpr text not null references pgp_keypair (fpr)\n"
  14.212 @@ -1117,6 +1169,40 @@
  14.213                  );
  14.214                  assert(int_result == SQLITE_OK);    
  14.215              }
  14.216 +            if (version < 10 && version > 1) {
  14.217 +                int_result = sqlite3_exec(
  14.218 +                    _session->db,                
  14.219 +                    "PRAGMA foreign_keys=off;\n"
  14.220 +                    "BEGIN TRANSACTION;\n"
  14.221 +                    "ALTER TABLE person RENAME TO _person_old;\n"                
  14.222 +                    "create table if not exists person (\n"
  14.223 +                    "   id text primary key,\n"
  14.224 +                    "   username text not null,\n"
  14.225 +                    "   main_key_id text\n"
  14.226 +                    "       references pgp_keypair (fpr)\n"
  14.227 +                    "       on delete set null,\n"
  14.228 +                    "   lang text,\n"
  14.229 +                    "   comment text,\n"
  14.230 +                    "   is_pEp_user integer default 0\n"
  14.231 +                    ");\n"
  14.232 +                    "INSERT INTO person (id, username, main_key_id, "
  14.233 +                    "                    lang, comment, is_pEp_user) "
  14.234 +                    "   SELECT _person_old.id, _person_old.username, "
  14.235 +                    "          _person_old.main_key_id, _person_old.lang, "
  14.236 +                    "          _person_old.comment, _person_old.is_pEp_user "
  14.237 +                    "   FROM _person_old "
  14.238 +                    "   WHERE 1;\n"
  14.239 +                    "DROP TABLE _person_old;\n"
  14.240 +                    "COMMIT;\n"
  14.241 +                    "\n"
  14.242 +                    "PRAGMA foreign_keys=on;\n"
  14.243 +                    ,
  14.244 +                    NULL,
  14.245 +                    NULL,
  14.246 +                    NULL
  14.247 +                );
  14.248 +                assert(int_result == SQLITE_OK);    
  14.249 +            }
  14.250          }        
  14.251          else { 
  14.252              // Version from DB was 0, it means this is initial setup.
  14.253 @@ -1288,13 +1374,13 @@
  14.254              &_session->get_own_address_binding_from_contact, NULL);
  14.255      assert(int_result == SQLITE_OK);
  14.256  
  14.257 -    int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  14.258 -            (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  14.259 -    assert(int_result == SQLITE_OK);
  14.260 -
  14.261 -    int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  14.262 -            (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  14.263 -    assert(int_result == SQLITE_OK);
  14.264 +    // int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  14.265 +    //         (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  14.266 +    // assert(int_result == SQLITE_OK);
  14.267 +    // 
  14.268 +    // int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  14.269 +    //         (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  14.270 +    // assert(int_result == SQLITE_OK);
  14.271  
  14.272      int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  14.273              (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  14.274 @@ -1399,6 +1485,11 @@
  14.275              (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  14.276              NULL);
  14.277      assert(int_result == SQLITE_OK);
  14.278 +
  14.279 +    int_result = sqlite3_prepare_v2(_session->db, sql_is_own_address,
  14.280 +            (int)strlen(sql_is_own_address), &_session->is_own_address,
  14.281 +            NULL);
  14.282 +    assert(int_result == SQLITE_OK);
  14.283      
  14.284      int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  14.285              (int)strlen(sql_own_identities_retrieve),
  14.286 @@ -1521,6 +1612,7 @@
  14.287          out_last = true;
  14.288  
  14.289      if (session) {
  14.290 +        free_Sync_state(session);
  14.291  
  14.292          if (session->db) {
  14.293              if (session->log)
  14.294 @@ -1573,10 +1665,10 @@
  14.295                  sqlite3_finalize(session->was_id_for_revoke_contacted);   
  14.296              if (session->get_last_contacted)
  14.297                  sqlite3_finalize(session->get_last_contacted);                                       
  14.298 -            if (session->set_device_group)
  14.299 -                sqlite3_finalize(session->set_device_group);
  14.300 -            if (session->get_device_group)
  14.301 -                sqlite3_finalize(session->get_device_group);
  14.302 +            // if (session->set_device_group)
  14.303 +            //     sqlite3_finalize(session->set_device_group);
  14.304 +            // if (session->get_device_group)
  14.305 +            //     sqlite3_finalize(session->get_device_group);
  14.306              if (session->set_pgp_keypair)
  14.307                  sqlite3_finalize(session->set_pgp_keypair);
  14.308              if (session->exists_identity_entry)
  14.309 @@ -1633,6 +1725,8 @@
  14.310                  sqlite3_finalize(session->blacklist_retrieve);
  14.311              if (session->own_key_is_listed)
  14.312                  sqlite3_finalize(session->own_key_is_listed);
  14.313 +            if (session->is_own_address)
  14.314 +                sqlite3_finalize(session->is_own_address);
  14.315              if (session->own_identities_retrieve)
  14.316                  sqlite3_finalize(session->own_identities_retrieve);
  14.317              if (session->own_keys_retrieve)
  14.318 @@ -1692,12 +1786,6 @@
  14.319      session->unencrypted_subject = enable;
  14.320  }
  14.321  
  14.322 -DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  14.323 -{
  14.324 -    assert(session);
  14.325 -    session->keep_sync_msg = enable;
  14.326 -}
  14.327 -
  14.328  DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  14.329  {
  14.330      assert(session);
  14.331 @@ -1712,7 +1800,12 @@
  14.332          const char *comment
  14.333      )
  14.334  {
  14.335 -//    PEP_STATUS status = PEP_STATUS_OK;
  14.336 +#ifndef NDEBUG
  14.337 +    fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
  14.338 +    session->service_log = true;
  14.339 +#endif
  14.340 +
  14.341 +    // PEP_STATUS status = PEP_STATUS_OK;
  14.342      // int result;
  14.343      // 
  14.344      // assert(session);
  14.345 @@ -2934,6 +3027,40 @@
  14.346      return PEP_STATUS_OK;
  14.347  }
  14.348  
  14.349 +PEP_STATUS is_own_address(PEP_SESSION session, const char* address, bool* is_own_addr)
  14.350 +{
  14.351 +    assert(session);
  14.352 +    assert(is_own_addr);
  14.353 +    assert(!EMPTYSTR(address));
  14.354 +
  14.355 +    if (!session || !is_own_addr || EMPTYSTR(address))
  14.356 +        return PEP_ILLEGAL_VALUE;
  14.357 +    
  14.358 +    *is_own_addr = false;
  14.359 +                
  14.360 +    if (!session || EMPTYSTR(address))
  14.361 +        return PEP_ILLEGAL_VALUE;
  14.362 +        
  14.363 +    sqlite3_reset(session->is_own_address);
  14.364 +    sqlite3_bind_text(session->is_own_address, 1, address, -1,
  14.365 +            SQLITE_STATIC);
  14.366 +    int result = sqlite3_step(session->is_own_address);
  14.367 +    switch (result) {
  14.368 +        case SQLITE_ROW: {
  14.369 +            // yeah yeah, I know, we could be lazy here, but it looks bad.
  14.370 +            *is_own_addr = (sqlite3_column_int(session->is_own_address, 0) != 0);
  14.371 +            break;
  14.372 +        }
  14.373 +        default:
  14.374 +            sqlite3_reset(session->is_own_address);
  14.375 +            return PEP_RECORD_NOT_FOUND;
  14.376 +    }
  14.377 +
  14.378 +    sqlite3_reset(session->is_own_address);
  14.379 +    
  14.380 +    return PEP_STATUS_OK;
  14.381 +}
  14.382 +
  14.383  PEP_STATUS bind_own_ident_with_contact_ident(PEP_SESSION session,
  14.384                                               pEp_identity* own_ident, 
  14.385                                               pEp_identity* contact_ident) {
  14.386 @@ -3069,93 +3196,93 @@
  14.387      return PEP_STATUS_OK;
  14.388  }
  14.389  
  14.390 -DYNAMIC_API PEP_STATUS set_device_group(
  14.391 -        PEP_SESSION session,
  14.392 -        const char *group_name
  14.393 -    )
  14.394 -{
  14.395 -    int result;
  14.396 -
  14.397 -    assert(session);
  14.398 -
  14.399 -    if (!(session && group_name))
  14.400 -        return PEP_ILLEGAL_VALUE;
  14.401 -
  14.402 -    // 1. Get own user_id
  14.403 -    char* user_id = NULL;
  14.404 -    PEP_STATUS status = get_default_own_userid(session, &user_id);
  14.405 -    
  14.406 -    // No user_id is returned in this case, no need to free;
  14.407 -    if (status != PEP_STATUS_OK)
  14.408 -        return status;
  14.409 -        
  14.410 -    // 2. Set device group
  14.411 -    sqlite3_reset(session->set_device_group);
  14.412 -    if(group_name){
  14.413 -        sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  14.414 -                SQLITE_STATIC);
  14.415 -    } else {
  14.416 -        sqlite3_bind_null(session->set_device_group, 1);
  14.417 -    }
  14.418 -    
  14.419 -    sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  14.420 -            SQLITE_STATIC);
  14.421 -
  14.422 -    result = sqlite3_step(session->set_device_group);
  14.423 -    sqlite3_reset(session->set_device_group);
  14.424 -    
  14.425 -    free(user_id);
  14.426 -    
  14.427 -    if (result != SQLITE_DONE)
  14.428 -        return PEP_CANNOT_SET_PERSON;
  14.429 -
  14.430 -    return PEP_STATUS_OK;
  14.431 -}
  14.432 -
  14.433 -DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  14.434 -{
  14.435 -    PEP_STATUS status = PEP_STATUS_OK;
  14.436 -    int result;
  14.437 -
  14.438 -    assert(session);
  14.439 -    assert(group_name);
  14.440 -
  14.441 -    if (!(session && group_name))
  14.442 -        return PEP_ILLEGAL_VALUE;
  14.443 -
  14.444 -    // 1. Get own user_id
  14.445 -    char* user_id = NULL;
  14.446 -    status = get_default_own_userid(session, &user_id);
  14.447 -    
  14.448 -    // No user_id is returned in this case, no need to free;
  14.449 -    if (status != PEP_STATUS_OK)
  14.450 -        return status;
  14.451 -
  14.452 -    // 2. get device group
  14.453 -    sqlite3_reset(session->get_device_group);
  14.454 -    sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  14.455 -            SQLITE_STATIC);
  14.456 -
  14.457 -    result = sqlite3_step(session->get_device_group);
  14.458 -    switch (result) {
  14.459 -    case SQLITE_ROW: {
  14.460 -        const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  14.461 -        if(_group_name){
  14.462 -            *group_name = strdup(_group_name);
  14.463 -                if(*group_name == NULL)
  14.464 -                    status = PEP_OUT_OF_MEMORY;
  14.465 -        }
  14.466 -        break;
  14.467 -    }
  14.468 - 
  14.469 -    default:
  14.470 -        status = PEP_RECORD_NOT_FOUND;
  14.471 -    }
  14.472 -
  14.473 -    free(user_id);
  14.474 -    sqlite3_reset(session->get_device_group);
  14.475 -    return status;
  14.476 -}
  14.477 +// DYNAMIC_API PEP_STATUS set_device_group(
  14.478 +//         PEP_SESSION session,
  14.479 +//         const char *group_name
  14.480 +//     )
  14.481 +// {
  14.482 +//     int result;
  14.483 +// 
  14.484 +//     assert(session);
  14.485 +// 
  14.486 +//     if (!(session && group_name))
  14.487 +//         return PEP_ILLEGAL_VALUE;
  14.488 +// 
  14.489 +//     // 1. Get own user_id
  14.490 +//     char* user_id = NULL;
  14.491 +//     PEP_STATUS status = get_default_own_userid(session, &user_id);
  14.492 +// 
  14.493 +//     // No user_id is returned in this case, no need to free;
  14.494 +//     if (status != PEP_STATUS_OK)
  14.495 +//         return status;
  14.496 +// 
  14.497 +//     // 2. Set device group
  14.498 +//     sqlite3_reset(session->set_device_group);
  14.499 +//     if(group_name){
  14.500 +//         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  14.501 +//                 SQLITE_STATIC);
  14.502 +//     } else {
  14.503 +//         sqlite3_bind_null(session->set_device_group, 1);
  14.504 +//     }
  14.505 +// 
  14.506 +//     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  14.507 +//             SQLITE_STATIC);
  14.508 +// 
  14.509 +//     result = sqlite3_step(session->set_device_group);
  14.510 +//     sqlite3_reset(session->set_device_group);
  14.511 +// 
  14.512 +//     free(user_id);
  14.513 +// 
  14.514 +//     if (result != SQLITE_DONE)
  14.515 +//         return PEP_CANNOT_SET_PERSON;
  14.516 +// 
  14.517 +//     return PEP_STATUS_OK;
  14.518 +// }
  14.519 +// 
  14.520 +// DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  14.521 +// {
  14.522 +//     PEP_STATUS status = PEP_STATUS_OK;
  14.523 +//     int result;
  14.524 +// 
  14.525 +//     assert(session);
  14.526 +//     assert(group_name);
  14.527 +// 
  14.528 +//     if (!(session && group_name))
  14.529 +//         return PEP_ILLEGAL_VALUE;
  14.530 +// 
  14.531 +//     // 1. Get own user_id
  14.532 +//     char* user_id = NULL;
  14.533 +//     status = get_default_own_userid(session, &user_id);
  14.534 +// 
  14.535 +//     // No user_id is returned in this case, no need to free;
  14.536 +//     if (status != PEP_STATUS_OK)
  14.537 +//         return status;
  14.538 +// 
  14.539 +//     // 2. get device group
  14.540 +//     sqlite3_reset(session->get_device_group);
  14.541 +//     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  14.542 +//             SQLITE_STATIC);
  14.543 +// 
  14.544 +//     result = sqlite3_step(session->get_device_group);
  14.545 +//     switch (result) {
  14.546 +//     case SQLITE_ROW: {
  14.547 +//         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  14.548 +//         if(_group_name){
  14.549 +//             *group_name = strdup(_group_name);
  14.550 +//                 if(*group_name == NULL)
  14.551 +//                     status = PEP_OUT_OF_MEMORY;
  14.552 +//         }
  14.553 +//         break;
  14.554 +//     }
  14.555 +// 
  14.556 +//     default:
  14.557 +//         status = PEP_RECORD_NOT_FOUND;
  14.558 +//     }
  14.559 +// 
  14.560 +//     free(user_id);
  14.561 +//     sqlite3_reset(session->get_device_group);
  14.562 +//     return status;
  14.563 +// }
  14.564  
  14.565  DYNAMIC_API PEP_STATUS set_identity_flags(
  14.566          PEP_SESSION session,
    15.1 --- a/src/pEpEngine.h	Thu Feb 07 16:02:11 2019 +0100
    15.2 +++ b/src/pEpEngine.h	Mon Apr 01 20:58:40 2019 +0200
    15.3 @@ -367,14 +367,6 @@
    15.4  DYNAMIC_API void config_use_only_own_private_keys(PEP_SESSION session, bool enable);
    15.5  
    15.6  
    15.7 -// config_keep_sync_msg() - do not remove sync messages (for debugging purposes)
    15.8 -//
    15.9 -//      session (in)    session handle
   15.10 -//      enable (in)     flag if enabled or disabled
   15.11 -
   15.12 -DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable);
   15.13 -
   15.14 -
   15.15  // config_service_log() - log more for service purposes
   15.16  //
   15.17  //      session (in)    session handle
   15.18 @@ -873,38 +865,38 @@
   15.19          const char* alias_id);
   15.20  
   15.21  
   15.22 -// set_device_group() - update own person's device group
   15.23 -//
   15.24 -//    parameters:
   15.25 -//        session (in)        session handle
   15.26 -//        group_name (in)     new group name
   15.27 -//
   15.28 -//    return value:
   15.29 -//        PEP_STATUS_OK = 0             device group was updated
   15.30 -//        PEP_CANNOT_SET_PERSON         update failed
   15.31 -
   15.32 -DYNAMIC_API PEP_STATUS set_device_group(
   15.33 -        PEP_SESSION session,
   15.34 -        const char *group_name
   15.35 -    );
   15.36 -
   15.37 -// get_device_group() - get own person's device group
   15.38 -//
   15.39 -//    parameters:
   15.40 -//        session (in)        session handle
   15.41 -//        group_name (in)     new group name
   15.42 -//
   15.43 -//    return value:
   15.44 -//        PEP_STATUS_OK = 0             couldn't get device group
   15.45 -//        PEP_RECORD_NOT_FOUND          update failed
   15.46 -//
   15.47 -//    caveat:
   15.48 -//        the ownerships of group_name is going to the caller
   15.49 -
   15.50 -DYNAMIC_API PEP_STATUS get_device_group(
   15.51 -        PEP_SESSION session, 
   15.52 -        char **group_name
   15.53 -    );
   15.54 +// // set_device_group() - update own person's device group
   15.55 +// //
   15.56 +// //    parameters:
   15.57 +// //        session (in)        session handle
   15.58 +// //        group_name (in)     new group name
   15.59 +// //
   15.60 +// //    return value:
   15.61 +// //        PEP_STATUS_OK = 0             device group was updated
   15.62 +// //        PEP_CANNOT_SET_PERSON         update failed
   15.63 +// 
   15.64 +// DYNAMIC_API PEP_STATUS set_device_group(
   15.65 +//         PEP_SESSION session,
   15.66 +//         const char *group_name
   15.67 +//     );
   15.68 +// 
   15.69 +// // get_device_group() - get own person's device group
   15.70 +// //
   15.71 +// //    parameters:
   15.72 +// //        session (in)        session handle
   15.73 +// //        group_name (in)     new group name
   15.74 +// //
   15.75 +// //    return value:
   15.76 +// //        PEP_STATUS_OK = 0             couldn't get device group
   15.77 +// //        PEP_RECORD_NOT_FOUND          update failed
   15.78 +// //
   15.79 +// //    caveat:
   15.80 +// //        the ownerships of group_name is going to the caller
   15.81 +// 
   15.82 +// DYNAMIC_API PEP_STATUS get_device_group(
   15.83 +//         PEP_SESSION session, 
   15.84 +//         char **group_name
   15.85 +//     );
   15.86  
   15.87  // set_identity_flags() - update identity flags on existing identity
   15.88  //
   15.89 @@ -1455,6 +1447,10 @@
   15.90          identity_list **identities
   15.91      );    
   15.92          
   15.93 +PEP_STATUS is_own_address(PEP_SESSION session, 
   15.94 +                          const char* address, 
   15.95 +                          bool* is_own_addr);
   15.96 +
   15.97  PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
   15.98                                const char* new_uid);
   15.99                                
  15.100 @@ -1521,7 +1517,9 @@
  15.101                       const char *fpr, 
  15.102                       char **sign, 
  15.103                       size_t *sign_size);
  15.104 -                     
  15.105 +
  15.106 +const char *get_device_name(PEP_SESSION session);
  15.107 +
  15.108  #ifdef __cplusplus
  15.109  }
  15.110  #endif
    16.1 --- a/src/pEp_internal.h	Thu Feb 07 16:02:11 2019 +0100
    16.2 +++ b/src/pEp_internal.h	Mon Apr 01 20:58:40 2019 +0200
    16.3 @@ -128,7 +128,6 @@
    16.4  #elif defined(USE_NETPGP)
    16.5      pEpNetPGPSession ctx;
    16.6  #elif defined(USE_SEQUOIA)
    16.7 -    sq_context_t ctx;
    16.8      sqlite3 *key_db;
    16.9      struct {
   16.10          sqlite3_stmt *begin_transaction;
   16.11 @@ -179,8 +178,8 @@
   16.12      sqlite3_stmt *get_contacted_ids_from_revoke_fpr;
   16.13      sqlite3_stmt *was_id_for_revoke_contacted;
   16.14      sqlite3_stmt *get_last_contacted;
   16.15 -    sqlite3_stmt *set_device_group;
   16.16 -    sqlite3_stmt *get_device_group;
   16.17 +    // sqlite3_stmt *set_device_group;
   16.18 +    // sqlite3_stmt *get_device_group;
   16.19      sqlite3_stmt *set_pgp_keypair;
   16.20      sqlite3_stmt *set_identity_entry;
   16.21      sqlite3_stmt *update_identity_entry;
   16.22 @@ -210,6 +209,7 @@
   16.23      
   16.24      // Keys
   16.25      sqlite3_stmt *own_key_is_listed;
   16.26 +    sqlite3_stmt *is_own_address;
   16.27      sqlite3_stmt *own_identities_retrieve;
   16.28      sqlite3_stmt *own_keys_retrieve;
   16.29      sqlite3_stmt *get_user_default_key;
   16.30 @@ -241,13 +241,13 @@
   16.31      // callbacks
   16.32      examine_identity_t examine_identity;
   16.33      void *examine_management;
   16.34 -    void *sync_management;
   16.35 -    void *sync_obj;
   16.36      notifyHandshake_t notifyHandshake;
   16.37      inject_sync_event_t inject_sync_event;
   16.38      retrieve_next_sync_event_t retrieve_next_sync_event;
   16.39  
   16.40      // pEp Sync
   16.41 +    void *sync_management;
   16.42 +    void *sync_obj;
   16.43      struct Sync_state_s sync_state;
   16.44      struct own_Sync_state_s own_sync_state;
   16.45  
   16.46 @@ -260,7 +260,6 @@
   16.47  
   16.48      bool passive_mode;
   16.49      bool unencrypted_subject;
   16.50 -    bool keep_sync_msg;
   16.51      bool service_log;
   16.52      
   16.53  #ifdef DEBUG_ERRORSTACK
    17.1 --- a/src/pgp_sequoia.c	Thu Feb 07 16:02:11 2019 +0100
    17.2 +++ b/src/pgp_sequoia.c	Mon Apr 01 20:58:40 2019 +0200
    17.3 @@ -10,13 +10,12 @@
    17.4  #include <limits.h>
    17.5  #include <sys/stat.h>
    17.6  #include <sys/types.h>
    17.7 -#include <error.h>
    17.8  
    17.9  #include <sqlite3.h>
   17.10  
   17.11  #include "wrappers.h"
   17.12  
   17.13 -#define TRACE 0
   17.14 +#define TRACING 0
   17.15  #ifndef TRACING
   17.16  #  ifndef NDEBUG
   17.17  #    define TRACING 0
   17.18 @@ -47,25 +46,22 @@
   17.19  } while(0)
   17.20  
   17.21  // Verbosely displays errors.
   17.22 -#  define DUMP_ERR(__de_session, __de_status, ...) do {             \
   17.23 -    TC(__VA_ARGS__);                                                \
   17.24 -    _T(": ");                                                       \
   17.25 -    if ((__de_session->ctx)) {                                      \
   17.26 -        sq_error_t __de_err                                         \
   17.27 -            = sq_context_last_error((__de_session->ctx));           \
   17.28 -        if (__de_err)                                               \
   17.29 -            _T("Sequoia: %s => ", sq_error_string(__de_err));       \
   17.30 -        sq_error_free(__de_err);                                    \
   17.31 -    }                                                               \
   17.32 -    _T("%s\n", pep_status_to_string(__de_status));                  \
   17.33 +#  define DUMP_ERR(__de_err, __de_status, ...) do {             \
   17.34 +    TC(__VA_ARGS__);                                            \
   17.35 +    _T(": ");                                                   \
   17.36 +    if (__de_err) {                                             \
   17.37 +        _T("Sequoia: %s => ", pgp_error_to_string(__de_err));   \
   17.38 +        pgp_error_free(__de_err);                               \
   17.39 +    }                                                           \
   17.40 +    _T("%s\n", pep_status_to_string(__de_status));              \
   17.41  } while(0)
   17.42  
   17.43  // If __ec_status is an error, then disable the error, set 'status' to
   17.44  // it, and jump to 'out'.
   17.45 -#define ERROR_OUT(__e_session, __ec_status, ...) do {               \
   17.46 +#define ERROR_OUT(__e_err, __ec_status, ...) do {                   \
   17.47      PEP_STATUS ___ec_status = (__ec_status);                        \
   17.48      if ((___ec_status) != PEP_STATUS_OK) {                          \
   17.49 -        DUMP_ERR((__e_session), (___ec_status), ##__VA_ARGS__);     \
   17.50 +        DUMP_ERR((__e_err), (___ec_status), ##__VA_ARGS__);         \
   17.51          status = (___ec_status);                                    \
   17.52          goto out;                                                   \
   17.53      }                                                               \
   17.54 @@ -75,22 +71,16 @@
   17.55  {
   17.56      PEP_STATUS status = PEP_STATUS_OK;
   17.57  
   17.58 -    sq_error_t err;
   17.59 -    session->ctx = sq_context_new("foundation.pep", &err);
   17.60 -    if (session->ctx == NULL)
   17.61 -        ERROR_OUT(session, PEP_INIT_GPGME_INIT_FAILED,
   17.62 -                  "initializing sequoia context");
   17.63 -
   17.64      // Create the home directory.
   17.65      char *home_env = getenv("HOME");
   17.66      if (!home_env)
   17.67 -        ERROR_OUT(session, PEP_INIT_GPGME_INIT_FAILED, "HOME unset");
   17.68 +        ERROR_OUT(NULL, PEP_INIT_GPGME_INIT_FAILED, "HOME unset");
   17.69  
   17.70      // Create the DB and initialize it.
   17.71      char *path = NULL;
   17.72      asprintf(&path, "%s/.pEp_keys.db", home_env);
   17.73      if (!path)
   17.74 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
   17.75 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
   17.76  
   17.77      int sqlite_result;
   17.78      sqlite_result = sqlite3_open_v2(path,
   17.79 @@ -102,9 +92,8 @@
   17.80                                      NULL);
   17.81      free(path);
   17.82      if (sqlite_result != SQLITE_OK)
   17.83 -        ERROR_OUT(session, PEP_INIT_CANNOT_OPEN_DB,
   17.84 -                  "opening keys DB: %s",
   17.85 -                  sqlite3_errmsg(session->key_db));
   17.86 +        ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   17.87 +                  "opening keys DB: %s", sqlite3_errmsg(session->key_db));
   17.88  
   17.89      sqlite_result = sqlite3_exec(session->key_db,
   17.90                                   "PRAGMA secure_delete=true;\n"
   17.91 @@ -113,7 +102,7 @@
   17.92                                   "PRAGMA journal_mode=WAL;\n",
   17.93                                   NULL, NULL, NULL);
   17.94      if (sqlite_result != SQLITE_OK)
   17.95 -        ERROR_OUT(session, PEP_INIT_CANNOT_OPEN_DB,
   17.96 +        ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
   17.97                    "setting pragmas: %s", sqlite3_errmsg(session->key_db));
   17.98  
   17.99      sqlite3_busy_timeout(session->key_db, BUSY_WAIT_TIME);
  17.100 @@ -128,7 +117,7 @@
  17.101                                   "  ON keys (primary_key, secret)\n",
  17.102                                   NULL, NULL, NULL);
  17.103      if (sqlite_result != SQLITE_OK)
  17.104 -        ERROR_OUT(session, PEP_INIT_CANNOT_OPEN_DB,
  17.105 +        ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
  17.106                    "creating keys table: %s",
  17.107                    sqlite3_errmsg(session->key_db));
  17.108  
  17.109 @@ -145,7 +134,7 @@
  17.110                                   "  ON subkeys (subkey, primary_key)\n",
  17.111                                   NULL, NULL, NULL);
  17.112      if (sqlite_result != SQLITE_OK)
  17.113 -        ERROR_OUT(session, PEP_INIT_CANNOT_OPEN_DB,
  17.114 +        ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
  17.115                    "creating subkeys table: %s",
  17.116                    sqlite3_errmsg(session->key_db));
  17.117  
  17.118 @@ -162,7 +151,7 @@
  17.119                                   "  ON userids (userid, primary_key)\n",
  17.120                                   NULL, NULL, NULL);
  17.121      if (sqlite_result != SQLITE_OK)
  17.122 -        ERROR_OUT(session, PEP_INIT_CANNOT_OPEN_DB,
  17.123 +        ERROR_OUT(NULL, PEP_INIT_CANNOT_OPEN_DB,
  17.124                    "creating userids table: %s",
  17.125                    sqlite3_errmsg(session->key_db));
  17.126  
  17.127 @@ -294,28 +283,23 @@
  17.128      if (session->key_db) {
  17.129          int result = sqlite3_close_v2(session->key_db);
  17.130          if (result != 0)
  17.131 -            DUMP_ERR(session, PEP_UNKNOWN_ERROR,
  17.132 +            DUMP_ERR(NULL, PEP_UNKNOWN_ERROR,
  17.133                       "Closing key DB: sqlite3_close_v2: %s",
  17.134                       sqlite3_errstr(result));
  17.135          session->key_db = NULL;
  17.136      }
  17.137 -
  17.138 -    if (session->ctx) {
  17.139 -        sq_context_free(session->ctx);
  17.140 -        session->ctx = NULL;
  17.141 -    }
  17.142  }
  17.143  
  17.144  // Ensures that a fingerprint is in canonical form.  A canonical
  17.145  // fingerprint doesn't contain any white space.
  17.146  //
  17.147  // This function does *not* consume fpr.
  17.148 -static char *sq_fingerprint_canonicalize(const char *) __attribute__((nonnull));
  17.149 -static char *sq_fingerprint_canonicalize(const char *fpr)
  17.150 +static char *pgp_fingerprint_canonicalize(const char *) __attribute__((nonnull));
  17.151 +static char *pgp_fingerprint_canonicalize(const char *fpr)
  17.152  {
  17.153 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
  17.154 -    char *fpr_canonicalized = sq_fingerprint_to_hex(sq_fpr);
  17.155 -    sq_fingerprint_free(sq_fpr);
  17.156 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  17.157 +    char *fpr_canonicalized = pgp_fingerprint_to_hex(pgp_fpr);
  17.158 +    pgp_fingerprint_free(pgp_fpr);
  17.159  
  17.160      return fpr_canonicalized;
  17.161  }
  17.162 @@ -374,10 +358,10 @@
  17.163  }
  17.164  
  17.165  // step statement and load the tpk and secret.
  17.166 -static PEP_STATUS key_load(PEP_SESSION, sqlite3_stmt *, sq_tpk_t *, int *)
  17.167 +static PEP_STATUS key_load(PEP_SESSION, sqlite3_stmt *, pgp_tpk_t *, int *)
  17.168      __attribute__((nonnull(1, 2)));
  17.169  static PEP_STATUS key_load(PEP_SESSION session, sqlite3_stmt *stmt,
  17.170 -                           sq_tpk_t *tpkp, int *secretp)
  17.171 +                           pgp_tpk_t *tpkp, int *secretp)
  17.172  {
  17.173      PEP_STATUS status = PEP_STATUS_OK;
  17.174      int sqlite_result = sqlite3_step(stmt);
  17.175 @@ -387,9 +371,10 @@
  17.176              int data_len = sqlite3_column_bytes(stmt, 0);
  17.177              const void *data = sqlite3_column_blob(stmt, 0);
  17.178  
  17.179 -            *tpkp = sq_tpk_from_bytes(session->ctx, data, data_len);
  17.180 +            pgp_error_t err = NULL;
  17.181 +            *tpkp = pgp_tpk_from_bytes(&err, data, data_len);
  17.182              if (!*tpkp)
  17.183 -                ERROR_OUT(session, PEP_GET_KEY_FAILED, "parsing TPK");
  17.184 +                ERROR_OUT(err, PEP_GET_KEY_FAILED, "parsing TPK");
  17.185          }
  17.186  
  17.187          if (secretp)
  17.188 @@ -401,7 +386,7 @@
  17.189          status = PEP_KEY_NOT_FOUND;
  17.190          break;
  17.191      default:
  17.192 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.193 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.194                    "stepping: %s", sqlite3_errmsg(session->key_db));
  17.195      }
  17.196  
  17.197 @@ -411,32 +396,32 @@
  17.198  }
  17.199  
  17.200  // step statement until exhausted and load the tpks.
  17.201 -static PEP_STATUS key_loadn(PEP_SESSION, sqlite3_stmt *, sq_tpk_t **, int *)
  17.202 +static PEP_STATUS key_loadn(PEP_SESSION, sqlite3_stmt *, pgp_tpk_t **, int *)
  17.203      __attribute__((nonnull));
  17.204  static PEP_STATUS key_loadn(PEP_SESSION session, sqlite3_stmt *stmt,
  17.205 -                            sq_tpk_t **tpksp, int *tpks_countp)
  17.206 +                            pgp_tpk_t **tpksp, int *tpks_countp)
  17.207  {
  17.208      PEP_STATUS status = PEP_STATUS_OK;
  17.209      int tpks_count = 0;
  17.210      int tpks_capacity = 8;
  17.211 -    sq_tpk_t *tpks = calloc(tpks_capacity, sizeof(sq_tpk_t));
  17.212 +    pgp_tpk_t *tpks = calloc(tpks_capacity, sizeof(pgp_tpk_t));
  17.213      if (!tpks)
  17.214 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
  17.215 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  17.216  
  17.217      for (;;) {
  17.218 -        sq_tpk_t tpk = NULL;
  17.219 +        pgp_tpk_t tpk = NULL;
  17.220          status = key_load(session, stmt, &tpk, NULL);
  17.221          if (status == PEP_KEY_NOT_FOUND) {
  17.222              status = PEP_STATUS_OK;
  17.223              break;
  17.224          }
  17.225 -        ERROR_OUT(session, status, "loading TPK");
  17.226 +        ERROR_OUT(NULL, status, "loading TPK");
  17.227  
  17.228          if (tpks_count == tpks_capacity) {
  17.229              tpks_capacity *= 2;
  17.230              tpks = realloc(tpks, sizeof(tpks[0]) * tpks_capacity);
  17.231              if (!tpks)
  17.232 -                ERROR_OUT(session, PEP_OUT_OF_MEMORY, "tpks");
  17.233 +                ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "tpks");
  17.234          }
  17.235          tpks[tpks_count ++] = tpk;
  17.236      }
  17.237 @@ -444,7 +429,7 @@
  17.238   out:
  17.239      if (status != PEP_STATUS_OK) {
  17.240          for (int i = 0; i < tpks_count; i ++)
  17.241 -            sq_tpk_free(tpks[i]);
  17.242 +            pgp_tpk_free(tpks[i]);
  17.243          free(tpks);
  17.244      } else {
  17.245          *tpksp = tpks;
  17.246 @@ -458,22 +443,23 @@
  17.247  // Returns the TPK identified by the provided fingerprint.
  17.248  //
  17.249  // This function only matches on the primary key!
  17.250 -static PEP_STATUS tpk_find(PEP_SESSION, sq_fingerprint_t, int, sq_tpk_t *, int *)
  17.251 +static PEP_STATUS tpk_find(PEP_SESSION, pgp_fingerprint_t, int, pgp_tpk_t *, int *)
  17.252      __attribute__((nonnull(1, 2)));
  17.253  static PEP_STATUS tpk_find(PEP_SESSION session,
  17.254 -                           sq_fingerprint_t fpr, int private_only,
  17.255 -                           sq_tpk_t *tpk, int *secret)
  17.256 +                           pgp_fingerprint_t fpr, int private_only,
  17.257 +                           pgp_tpk_t *tpk, int *secret)
  17.258  {
  17.259      PEP_STATUS status = PEP_STATUS_OK;
  17.260 -    char *fpr_str = sq_fingerprint_to_hex(fpr);
  17.261 +    char *fpr_str = pgp_fingerprint_to_hex(fpr);
  17.262  
  17.263      T("(%s, %d)", fpr_str, private_only);
  17.264  
  17.265 -    sqlite3_stmt *stmt = private_only ? session->sq_sql.tsk_find : session->sq_sql.tpk_find;
  17.266 +    sqlite3_stmt *stmt
  17.267 +        = private_only ? session->sq_sql.tsk_find : session->sq_sql.tpk_find;
  17.268      sqlite3_bind_text(stmt, 1, fpr_str, -1, SQLITE_STATIC);
  17.269  
  17.270      status = key_load(session, stmt, tpk, secret);
  17.271 -    ERROR_OUT(session, status, "Looking up %s", fpr_str);
  17.272 +    ERROR_OUT(NULL, status, "Looking up %s", fpr_str);
  17.273  
  17.274   out:
  17.275      sqlite3_reset(stmt);
  17.276 @@ -493,11 +479,11 @@
  17.277  //
  17.278  // If private_only is set, this will only consider TPKs with some
  17.279  // secret key material.
  17.280 -static PEP_STATUS tpk_find_by_keyid_hex(PEP_SESSION, const char *, int, sq_tpk_t *, int *)
  17.281 +static PEP_STATUS tpk_find_by_keyid_hex(PEP_SESSION, const char *, int, pgp_tpk_t *, int *)
  17.282    __attribute__((nonnull(1, 2)));
  17.283  static PEP_STATUS tpk_find_by_keyid_hex(
  17.284          PEP_SESSION session, const char *keyid_hex, int private_only,
  17.285 -        sq_tpk_t *tpkp, int *secretp)
  17.286 +        pgp_tpk_t *tpkp, int *secretp)
  17.287  {
  17.288      PEP_STATUS status = PEP_STATUS_OK;
  17.289      T("(%s, %d)", keyid_hex, private_only);
  17.290 @@ -507,7 +493,7 @@
  17.291      sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
  17.292  
  17.293      status = key_load(session, stmt, tpkp, secretp);
  17.294 -    ERROR_OUT(session, status, "Looking up %s", keyid_hex);
  17.295 +    ERROR_OUT(NULL, status, "Looking up %s", keyid_hex);
  17.296  
  17.297   out:
  17.298      sqlite3_reset(stmt);
  17.299 @@ -516,13 +502,13 @@
  17.300  }
  17.301  
  17.302  // See tpk_find_by_keyid_hex.
  17.303 -PEP_STATUS tpk_find_by_keyid(PEP_SESSION, sq_keyid_t, int, sq_tpk_t *, int *)
  17.304 +PEP_STATUS tpk_find_by_keyid(PEP_SESSION, pgp_keyid_t, int, pgp_tpk_t *, int *)
  17.305      __attribute__((nonnull(1, 2)));
  17.306  PEP_STATUS tpk_find_by_keyid(PEP_SESSION session,
  17.307 -                             sq_keyid_t keyid, int private_only,
  17.308 -                             sq_tpk_t *tpkp, int *secretp)
  17.309 +                             pgp_keyid_t keyid, int private_only,
  17.310 +                             pgp_tpk_t *tpkp, int *secretp)
  17.311  {
  17.312 -    char *keyid_hex = sq_keyid_to_hex(keyid);
  17.313 +    char *keyid_hex = pgp_keyid_to_hex(keyid);
  17.314      if (! keyid_hex)
  17.315          return PEP_OUT_OF_MEMORY;
  17.316      PEP_STATUS status
  17.317 @@ -532,46 +518,46 @@
  17.318  }
  17.319  
  17.320  // See tpk_find_by_keyid_hex.
  17.321 -static PEP_STATUS tpk_find_by_fpr(PEP_SESSION, sq_fingerprint_t, int,
  17.322 -                                  sq_tpk_t *, int *)
  17.323 +static PEP_STATUS tpk_find_by_fpr(PEP_SESSION, pgp_fingerprint_t, int,
  17.324 +                                  pgp_tpk_t *, int *)
  17.325      __attribute__((nonnull(1, 2)));
  17.326  static PEP_STATUS tpk_find_by_fpr(
  17.327 -    PEP_SESSION session, sq_fingerprint_t fpr, int private_only,
  17.328 -    sq_tpk_t *tpkp, int *secretp)
  17.329 +    PEP_SESSION session, pgp_fingerprint_t fpr, int private_only,
  17.330 +    pgp_tpk_t *tpkp, int *secretp)
  17.331  {
  17.332 -    sq_keyid_t keyid = sq_fingerprint_to_keyid(fpr);
  17.333 +    pgp_keyid_t keyid = pgp_fingerprint_to_keyid(fpr);
  17.334      if (! keyid)
  17.335          return PEP_OUT_OF_MEMORY;
  17.336      PEP_STATUS status
  17.337          = tpk_find_by_keyid(session, keyid, private_only, tpkp, secretp);
  17.338 -    sq_keyid_free(keyid);
  17.339 +    pgp_keyid_free(keyid);
  17.340      return status;
  17.341  }
  17.342  
  17.343  // See tpk_find_by_keyid_hex.
  17.344 -static PEP_STATUS tpk_find_by_fpr_hex(PEP_SESSION, const char *, int, sq_tpk_t *, int *secret)
  17.345 +static PEP_STATUS tpk_find_by_fpr_hex(PEP_SESSION, const char *, int, pgp_tpk_t *, int *secret)
  17.346      __attribute__((nonnull(1, 2)));
  17.347  static PEP_STATUS tpk_find_by_fpr_hex(
  17.348      PEP_SESSION session, const char *fpr, int private_only,
  17.349 -    sq_tpk_t *tpkp, int *secretp)
  17.350 +    pgp_tpk_t *tpkp, int *secretp)
  17.351  {
  17.352 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
  17.353 -    if (! sq_fpr)
  17.354 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
  17.355 +    if (! pgp_fpr)
  17.356          return PEP_OUT_OF_MEMORY;
  17.357      PEP_STATUS status
  17.358 -        = tpk_find_by_fpr(session, sq_fpr, private_only, tpkp, secretp);
  17.359 -    sq_fingerprint_free(sq_fpr);
  17.360 +        = tpk_find_by_fpr(session, pgp_fpr, private_only, tpkp, secretp);
  17.361 +    pgp_fingerprint_free(pgp_fpr);
  17.362      return status;
  17.363  }
  17.364  
  17.365  // Returns all known TPKs.
  17.366 -static PEP_STATUS tpk_all(PEP_SESSION, int, sq_tpk_t **, int *) __attribute__((nonnull));
  17.367 +static PEP_STATUS tpk_all(PEP_SESSION, int, pgp_tpk_t **, int *) __attribute__((nonnull));
  17.368  static PEP_STATUS tpk_all(PEP_SESSION session, int private_only,
  17.369 -                          sq_tpk_t **tpksp, int *tpks_countp) {
  17.370 +                          pgp_tpk_t **tpksp, int *tpks_countp) {
  17.371      PEP_STATUS status = PEP_STATUS_OK;
  17.372      sqlite3_stmt *stmt = private_only ? session->sq_sql.tsk_all : session->sq_sql.tpk_all;
  17.373      status = key_loadn(session, stmt, tpksp, tpks_countp);
  17.374 -    ERROR_OUT(session, status, "loading TPKs");
  17.375 +    ERROR_OUT(NULL, status, "loading TPKs");
  17.376   out:
  17.377      sqlite3_reset(stmt);
  17.378      return status;
  17.379 @@ -579,12 +565,12 @@
  17.380  
  17.381  // Returns keys that have a user id that matches the specified pattern.
  17.382  //
  17.383 -// The keys returned must be freed using sq_tpk_free.
  17.384 -static PEP_STATUS tpk_find_by_email(PEP_SESSION, const char *, int, sq_tpk_t **, int *)
  17.385 +// The keys returned must be freed using pgp_tpk_free.
  17.386 +static PEP_STATUS tpk_find_by_email(PEP_SESSION, const char *, int, pgp_tpk_t **, int *)
  17.387      __attribute__((nonnull));
  17.388  static PEP_STATUS tpk_find_by_email(PEP_SESSION session,
  17.389                                      const char *pattern, int private_only,
  17.390 -                                    sq_tpk_t **tpksp, int *countp)
  17.391 +                                    pgp_tpk_t **tpksp, int *countp)
  17.392  {
  17.393      PEP_STATUS status = PEP_STATUS_OK;
  17.394      T("(%s)", pattern);
  17.395 @@ -594,7 +580,7 @@
  17.396      sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_STATIC);
  17.397  
  17.398      status = key_loadn(session, stmt, tpksp, countp);
  17.399 -    ERROR_OUT(session, status, "Searching for '%s'", pattern);
  17.400 +    ERROR_OUT(NULL, status, "Searching for '%s'", pattern);
  17.401  
  17.402   out:
  17.403      sqlite3_reset(stmt);
  17.404 @@ -606,59 +592,63 @@
  17.405  // Saves the specified TPK.
  17.406  //
  17.407  // This function takes ownership of TPK.
  17.408 -static PEP_STATUS tpk_save(PEP_SESSION, sq_tpk_t, identity_list **)
  17.409 +static PEP_STATUS tpk_save(PEP_SESSION, pgp_tpk_t, identity_list **)
  17.410      __attribute__((nonnull(1, 2)));
  17.411 -static PEP_STATUS tpk_save(PEP_SESSION session, sq_tpk_t tpk,
  17.412 +static PEP_STATUS tpk_save(PEP_SESSION session, pgp_tpk_t tpk,
  17.413                             identity_list **private_idents)
  17.414  {
  17.415      PEP_STATUS status = PEP_STATUS_OK;
  17.416 -    sq_fingerprint_t sq_fpr = NULL;
  17.417 +    pgp_error_t err = NULL;
  17.418 +    pgp_fingerprint_t pgp_fpr = NULL;
  17.419      char *fpr = NULL;
  17.420      void *tsk_buffer = NULL;
  17.421      size_t tsk_buffer_len = 0;
  17.422      int tried_commit = 0;
  17.423 -    sq_tpk_key_iter_t key_iter = NULL;
  17.424 -    sq_user_id_binding_iter_t user_id_iter = NULL;
  17.425 +    pgp_tpk_key_iter_t key_iter = NULL;
  17.426 +    pgp_user_id_binding_iter_t user_id_iter = NULL;
  17.427  
  17.428 -    sq_fpr = sq_tpk_fingerprint(tpk);
  17.429 -    fpr = sq_fingerprint_to_hex(sq_fpr);
  17.430 -    T("(%s, private_idents: %s)", fpr, private_idents ? "yes" : "no");
  17.431 -
  17.432 -    // Merge any existing data into TPK.
  17.433 -    sq_tpk_t current = NULL;
  17.434 -    status = tpk_find(session, sq_fpr, false, &current, NULL);
  17.435 -    if (status == PEP_KEY_NOT_FOUND)
  17.436 -        status = PEP_STATUS_OK;
  17.437 -    else
  17.438 -        ERROR_OUT(session, status, "Looking up %s", fpr);
  17.439 -    if (current)
  17.440 -        tpk = sq_tpk_merge(session->ctx, tpk, current);
  17.441 -
  17.442 -    int is_tsk = sq_tpk_is_tsk(tpk);
  17.443 -
  17.444 -    // Serialize it.
  17.445 -    sq_writer_t writer = sq_writer_alloc(&tsk_buffer, &tsk_buffer_len);
  17.446 -    if (! writer)
  17.447 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
  17.448 -
  17.449 -    sq_status_t sq_status;
  17.450 -    sq_tsk_t tsk = sq_tpk_into_tsk(tpk);
  17.451 -    sq_status = sq_tsk_serialize(session->ctx, tsk, writer);
  17.452 -    tpk = sq_tsk_into_tpk(tsk);
  17.453 -    //sq_writer_free(writer);
  17.454 -    if (sq_status != 0)
  17.455 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Serializing TPK");
  17.456 -
  17.457 -
  17.458 -    // Insert the TSK into the DB.
  17.459      sqlite3_stmt *stmt = session->sq_sql.begin_transaction;
  17.460      int sqlite_result = sqlite3_step(stmt);
  17.461      sqlite3_reset(stmt);
  17.462      if (sqlite_result != SQLITE_DONE)
  17.463 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.464 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.465                    "begin transaction failed: %s",
  17.466                    sqlite3_errmsg(session->key_db));
  17.467  
  17.468 +    pgp_fpr = pgp_tpk_fingerprint(tpk);
  17.469 +    fpr = pgp_fingerprint_to_hex(pgp_fpr);
  17.470 +    T("(%s, private_idents: %s)", fpr, private_idents ? "yes" : "no");
  17.471 +
  17.472 +    // Merge any existing data into TPK.
  17.473 +    pgp_tpk_t current = NULL;
  17.474 +    status = tpk_find(session, pgp_fpr, false, &current, NULL);
  17.475 +    if (status == PEP_KEY_NOT_FOUND)
  17.476 +        status = PEP_STATUS_OK;
  17.477 +    else
  17.478 +        ERROR_OUT(NULL, status, "Looking up %s", fpr);
  17.479 +    if (current) {
  17.480 +        tpk = pgp_tpk_merge(&err, tpk, current);
  17.481 +        if (! tpk)
  17.482 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Merging TPKs");
  17.483 +    }
  17.484 +
  17.485 +    int is_tsk = pgp_tpk_is_tsk(tpk);
  17.486 +
  17.487 +    // Serialize it.
  17.488 +    pgp_writer_t writer = pgp_writer_alloc(&tsk_buffer, &tsk_buffer_len);
  17.489 +    if (! writer)
  17.490 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
  17.491 +
  17.492 +    pgp_status_t pgp_status;
  17.493 +    pgp_tsk_t tsk = pgp_tpk_into_tsk(tpk);
  17.494 +    pgp_status = pgp_tsk_serialize(&err, tsk, writer);
  17.495 +    tpk = pgp_tsk_into_tpk(tsk);
  17.496 +    //pgp_writer_free(writer);
  17.497 +    if (pgp_status != 0)
  17.498 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Serializing TPK");
  17.499 +
  17.500 +
  17.501 +    // Insert the TSK into the DB.
  17.502      stmt = session->sq_sql.tpk_save_insert_primary;
  17.503      sqlite3_bind_text(stmt, 1, fpr, -1, SQLITE_STATIC);
  17.504      sqlite3_bind_int(stmt, 2, is_tsk);
  17.505 @@ -667,45 +657,47 @@
  17.506      sqlite_result = sqlite3_step(stmt);
  17.507      sqlite3_reset(stmt);
  17.508      if (sqlite_result != SQLITE_DONE)
  17.509 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.510 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.511                    "Saving TPK: %s", sqlite3_errmsg(session->key_db));
  17.512  
  17.513      // Insert the "subkeys" (the primary key and the subkeys).
  17.514      stmt = session->sq_sql.tpk_save_insert_subkeys;
  17.515 -    key_iter = sq_tpk_key_iter(tpk);
  17.516 -    sq_p_key_t key;
  17.517 -    while ((key = sq_tpk_key_iter_next(key_iter, NULL, NULL))) {
  17.518 -        sq_keyid_t keyid = sq_p_key_keyid(key);
  17.519 -        char *keyid_hex = sq_keyid_to_hex(keyid);
  17.520 +    // This inserts all of the keys in the TPK, i.e., revoked and
  17.521 +    // expired keys, which is what we want.
  17.522 +    key_iter = pgp_tpk_key_iter_all(tpk);
  17.523 +    pgp_key_t key;
  17.524 +    while ((key = pgp_tpk_key_iter_next(key_iter, NULL, NULL))) {
  17.525 +        pgp_keyid_t keyid = pgp_key_keyid(key);
  17.526 +        char *keyid_hex = pgp_keyid_to_hex(keyid);
  17.527          sqlite3_bind_text(stmt, 1, keyid_hex, -1, SQLITE_STATIC);
  17.528          sqlite3_bind_text(stmt, 2, fpr, -1, SQLITE_STATIC);
  17.529  
  17.530          sqlite_result = sqlite3_step(stmt);
  17.531          sqlite3_reset(stmt);
  17.532          free(keyid_hex);
  17.533 -        sq_keyid_free(keyid);
  17.534 +        pgp_keyid_free(keyid);
  17.535          if (sqlite_result != SQLITE_DONE) {
  17.536 -            sq_tpk_key_iter_free(key_iter);
  17.537 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.538 +            pgp_tpk_key_iter_free(key_iter);
  17.539 +            ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.540                        "Updating subkeys: %s", sqlite3_errmsg(session->key_db));
  17.541          }
  17.542      }
  17.543 -    sq_tpk_key_iter_free(key_iter);
  17.544 +    pgp_tpk_key_iter_free(key_iter);
  17.545      key_iter = NULL;
  17.546  
  17.547      // Insert the "userids".
  17.548      stmt = session->sq_sql.tpk_save_insert_userids;
  17.549 -    user_id_iter = sq_tpk_user_id_binding_iter(tpk);
  17.550 -    sq_user_id_binding_t binding;
  17.551 +    user_id_iter = pgp_tpk_user_id_binding_iter(tpk);
  17.552 +    pgp_user_id_binding_t binding;
  17.553      int first = 1;
  17.554 -    while ((binding = sq_user_id_binding_iter_next(user_id_iter))) {
  17.555 -        char *user_id = sq_user_id_binding_user_id(binding);
  17.556 +    while ((binding = pgp_user_id_binding_iter_next(user_id_iter))) {
  17.557 +        char *user_id = pgp_user_id_binding_user_id(binding);
  17.558          if (!user_id || !*user_id)
  17.559              continue;
  17.560  
  17.561          // Ignore bindings with a self-revocation certificate, but no
  17.562          // self-signature.
  17.563 -        if (!sq_user_id_binding_selfsig(binding)) {
  17.564 +        if (!pgp_user_id_binding_selfsig(binding)) {
  17.565              free(user_id);
  17.566              continue;
  17.567          }
  17.568 @@ -724,9 +716,9 @@
  17.569              sqlite3_reset(stmt);
  17.570  
  17.571              if (sqlite_result != SQLITE_DONE) {
  17.572 -                sq_user_id_binding_iter_free(user_id_iter);
  17.573 +                pgp_user_id_binding_iter_free(user_id_iter);
  17.574                  free(name);
  17.575 -                ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.576 +                ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.577                            "Updating userids: %s", sqlite3_errmsg(session->key_db));
  17.578              }
  17.579          }
  17.580 @@ -737,17 +729,17 @@
  17.581              // Create an identity for the primary user id.
  17.582              pEp_identity *ident = new_identity(email, fpr, NULL, name);
  17.583              if (ident == NULL)
  17.584 -                ERROR_OUT(session, PEP_OUT_OF_MEMORY, "new_identity");
  17.585 +                ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_identity");
  17.586  
  17.587              *private_idents = identity_list_add(*private_idents, ident);
  17.588              if (*private_idents == NULL)
  17.589 -                ERROR_OUT(session, PEP_OUT_OF_MEMORY, "identity_list_add");
  17.590 +                ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "identity_list_add");
  17.591          }
  17.592          free(email);
  17.593          free(name);
  17.594  
  17.595      }
  17.596 -    sq_user_id_binding_iter_free(user_id_iter);
  17.597 +    pgp_user_id_binding_iter_free(user_id_iter);
  17.598      user_id_iter = NULL;
  17.599  
  17.600   out:
  17.601 @@ -760,7 +752,7 @@
  17.602          int sqlite_result = sqlite3_step(stmt);
  17.603          sqlite3_reset(stmt);
  17.604          if (sqlite_result != SQLITE_DONE)
  17.605 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR,
  17.606 +            ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
  17.607                        status == PEP_STATUS_OK
  17.608                        ? "commit failed: %s" : "rollback failed: %s",
  17.609                        sqlite3_errmsg(session->key_db));
  17.610 @@ -769,16 +761,16 @@
  17.611      T("(%s) -> %s", fpr, pep_status_to_string(status));
  17.612  
  17.613      if (user_id_iter)
  17.614 -        sq_user_id_binding_iter_free(user_id_iter);
  17.615 +        pgp_user_id_binding_iter_free(user_id_iter);
  17.616      if (key_iter)
  17.617 -        sq_tpk_key_iter_free(key_iter);
  17.618 +        pgp_tpk_key_iter_free(key_iter);
  17.619      if (stmt)
  17.620        sqlite3_reset(stmt);
  17.621      free(tsk_buffer);
  17.622      if (tpk)
  17.623 -        sq_tpk_free(tpk);
  17.624 +        pgp_tpk_free(tpk);
  17.625      free(fpr);
  17.626 -    sq_fingerprint_free(sq_fpr);
  17.627 +    pgp_fingerprint_free(pgp_fpr);
  17.628  
  17.629      return status;
  17.630  }
  17.631 @@ -794,10 +786,10 @@
  17.632      int decrypted;
  17.633  };
  17.634  
  17.635 -static sq_status_t
  17.636 +static pgp_status_t
  17.637  get_public_keys_cb(void *cookie_raw,
  17.638 -                   sq_keyid_t *keyids, size_t keyids_len,
  17.639 -                   sq_tpk_t **tpks, size_t *tpk_len,
  17.640 +                   pgp_keyid_t *keyids, size_t keyids_len,
  17.641 +                   pgp_tpk_t **tpks, size_t *tpk_len,
  17.642                     void (**our_free)(void *))
  17.643  {
  17.644      struct decrypt_cookie *cookie = cookie_raw;
  17.645 @@ -805,47 +797,48 @@
  17.646  
  17.647      *tpks = calloc(keyids_len, sizeof(*tpks));
  17.648      if (!*tpks)
  17.649 -        return SQ_STATUS_UNKNOWN_ERROR;
  17.650 +        return PGP_STATUS_UNKNOWN_ERROR;
  17.651      *our_free = free;
  17.652  
  17.653      int i, j;
  17.654      j = 0;
  17.655      for (i = 0; i < keyids_len; i ++) {
  17.656 -        sq_tpk_t tpk = NULL;
  17.657 -        sq_status_t status
  17.658 +        pgp_tpk_t tpk = NULL;
  17.659 +        pgp_status_t status
  17.660              = tpk_find_by_keyid(session, keyids[i], false, &tpk, NULL);
  17.661 -        if (status == SQ_STATUS_SUCCESS)
  17.662 +        if (status == PGP_STATUS_SUCCESS)
  17.663              (*tpks)[j ++] = tpk;
  17.664      }
  17.665      *tpk_len = j;
  17.666 -    return SQ_STATUS_SUCCESS;
  17.667 +    return PGP_STATUS_SUCCESS;
  17.668  }
  17.669  
  17.670 -static sq_status_t
  17.671 +static pgp_status_t
  17.672  get_secret_keys_cb(void *cookie_opaque,
  17.673 -                   sq_pkesk_t *pkesks, size_t pkesk_count,
  17.674 -                   sq_skesk_t *skesks, size_t skesk_count,
  17.675 -                   sq_secret_t *secret)
  17.676 +                   pgp_pkesk_t *pkesks, size_t pkesk_count,
  17.677 +                   pgp_skesk_t *skesks, size_t skesk_count,
  17.678 +                   pgp_secret_t *secret)
  17.679  {
  17.680 +    pgp_error_t err = NULL;
  17.681      struct decrypt_cookie *cookie = cookie_opaque;
  17.682      PEP_SESSION session = cookie->session;
  17.683 -    sq_tpk_t *tsks = NULL;
  17.684 +    pgp_tpk_t *tsks = NULL;
  17.685      int tsks_count = 0;
  17.686      int wildcards = 0;
  17.687  
  17.688      if (cookie->get_secret_keys_called)
  17.689          // Prevent iterations, which isn't needed since we don't
  17.690          // support SKESKs.
  17.691 -        return SQ_STATUS_UNKNOWN_ERROR;
  17.692 +        return PGP_STATUS_UNKNOWN_ERROR;
  17.693      cookie->get_secret_keys_called = 1;
  17.694  
  17.695      T("%zd PKESKs", pkesk_count);
  17.696  
  17.697      for (int i = 0; i < pkesk_count; i ++) {
  17.698 -        sq_pkesk_t pkesk = pkesks[i];
  17.699 -        sq_keyid_t keyid = sq_pkesk_recipient(pkesk); /* Reference. */
  17.700 -        char *keyid_str = sq_keyid_to_hex(keyid);
  17.701 -        sq_tpk_key_iter_t key_iter = NULL;
  17.702 +        pgp_pkesk_t pkesk = pkesks[i];
  17.703 +        pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  17.704 +        char *keyid_str = pgp_keyid_to_hex(keyid);
  17.705 +        pgp_tpk_key_iter_t key_iter = NULL;
  17.706  
  17.707          T("Considering PKESK for %s", keyid_str);
  17.708  
  17.709 @@ -857,31 +850,31 @@
  17.710  
  17.711          // Collect the recipients.  Note: we must return the primary
  17.712          // key's fingerprint.
  17.713 -        sq_tpk_t tpk = NULL;
  17.714 +        pgp_tpk_t tpk = NULL;
  17.715          int is_tsk = 0;
  17.716          if (tpk_find_by_keyid(session, keyid, false, &tpk, &is_tsk) != PEP_STATUS_OK)
  17.717              goto eol;
  17.718  
  17.719 -        sq_fingerprint_t fp = sq_tpk_fingerprint(tpk);
  17.720 -        char *fp_string = sq_fingerprint_to_hex(fp);
  17.721 +        pgp_fingerprint_t fp = pgp_tpk_fingerprint(tpk);
  17.722 +        char *fp_string = pgp_fingerprint_to_hex(fp);
  17.723          stringlist_add_unique(cookie->recipient_keylist, fp_string);
  17.724          free(fp_string);
  17.725 -        sq_fingerprint_free(fp);
  17.726 +        pgp_fingerprint_free(fp);
  17.727  
  17.728          if (cookie->decrypted)
  17.729              goto eol;
  17.730  
  17.731          // See if we have the secret key.
  17.732 -        assert(is_tsk == sq_tpk_is_tsk(tpk));
  17.733 +        assert(is_tsk == pgp_tpk_is_tsk(tpk));
  17.734          if (! is_tsk)
  17.735              goto eol;
  17.736  
  17.737 -        key_iter = sq_tpk_key_iter(tpk);
  17.738 -        sq_p_key_t key;
  17.739 -        while ((key = sq_tpk_key_iter_next(key_iter, NULL, NULL))) {
  17.740 -            sq_keyid_t this_keyid = sq_p_key_keyid(key);
  17.741 -            char *this_keyid_hex = sq_keyid_to_hex(this_keyid);
  17.742 -            sq_keyid_free(this_keyid);
  17.743 +        key_iter = pgp_tpk_key_iter_all(tpk);
  17.744 +        pgp_key_t key;
  17.745 +        while ((key = pgp_tpk_key_iter_next(key_iter, NULL, NULL))) {
  17.746 +            pgp_keyid_t this_keyid = pgp_key_keyid(key);
  17.747 +            char *this_keyid_hex = pgp_keyid_to_hex(this_keyid);
  17.748 +            pgp_keyid_free(this_keyid);
  17.749  
  17.750              int match = strcmp(keyid_str, this_keyid_hex) == 0;
  17.751              free(this_keyid_hex);
  17.752 @@ -897,53 +890,54 @@
  17.753          uint8_t algo;
  17.754          uint8_t session_key[1024];
  17.755          size_t session_key_len = sizeof(session_key);
  17.756 -        if (sq_pkesk_decrypt(cookie->session->ctx,
  17.757 -                             pkesk, key, &algo,
  17.758 -                             session_key, &session_key_len) != 0) {
  17.759 -            DUMP_ERR(session, PEP_UNKNOWN_ERROR, "sq_pkesk_decrypt");
  17.760 +        if (pgp_pkesk_decrypt(&err, pkesk, key, &algo,
  17.761 +                              session_key, &session_key_len) != 0) {
  17.762 +            DUMP_ERR(err, PEP_UNKNOWN_ERROR, "pgp_pkesk_decrypt");
  17.763              goto eol;
  17.764          }
  17.765  
  17.766          T("Decrypted PKESK for %s", keyid_str);
  17.767  
  17.768 -        *secret = sq_secret_cached(algo, session_key, session_key_len);
  17.769 +        *secret = pgp_secret_cached(algo, session_key, session_key_len);
  17.770          cookie->decrypted = 1;
  17.771  
  17.772      eol:
  17.773          free(keyid_str);
  17.774          if (key_iter)
  17.775 -            sq_tpk_key_iter_free(key_iter);
  17.776 +            pgp_tpk_key_iter_free(key_iter);
  17.777          if (tpk)
  17.778 -            sq_tpk_free(tpk);
  17.779 +            pgp_tpk_free(tpk);
  17.780      }
  17.781  
  17.782      // Consider wildcard recipients.
  17.783      if (wildcards) for (int i = 0; i < pkesk_count && !cookie->decrypted; i ++) {
  17.784 -        sq_pkesk_t pkesk = pkesks[i];
  17.785 -        sq_keyid_t keyid = sq_pkesk_recipient(pkesk); /* Reference. */
  17.786 -        char *keyid_str = sq_keyid_to_hex(keyid);
  17.787 -        sq_tpk_key_iter_t key_iter = NULL;
  17.788 +        pgp_pkesk_t pkesk = pkesks[i];
  17.789 +        pgp_keyid_t keyid = pgp_pkesk_recipient(pkesk); /* Reference. */
  17.790 +        char *keyid_str = pgp_keyid_to_hex(keyid);
  17.791 +        pgp_tpk_key_iter_t key_iter = NULL;
  17.792  
  17.793          if (strcmp(keyid_str, "0000000000000000") != 0)
  17.794              goto eol2;
  17.795  
  17.796          if (!tsks) {
  17.797              if (tpk_all(session, true, &tsks, &tsks_count) != PEP_STATUS_OK) {
  17.798 -                DUMP_ERR(session, PEP_UNKNOWN_ERROR, "Getting all tsks");
  17.799 +                DUMP_ERR(NULL, PEP_UNKNOWN_ERROR, "Getting all tsks");
  17.800              }
  17.801          }
  17.802  
  17.803          for (int j = 0; j < tsks_count; j ++) {
  17.804 -            sq_tpk_t tsk = tsks[j];
  17.805 +            pgp_tpk_t tsk = tsks[j];
  17.806  
  17.807 -            key_iter = sq_tpk_key_iter(tsk);
  17.808 -            sq_p_key_t key;
  17.809 -            sq_signature_t selfsig;
  17.810 -            while ((key = sq_tpk_key_iter_next(key_iter, &selfsig, NULL))) {
  17.811 -                if (! (sq_signature_can_encrypt_at_rest(selfsig)
  17.812 -                       || sq_signature_can_encrypt_for_transport(selfsig)))
  17.813 +            key_iter = pgp_tpk_key_iter_all(tsk);
  17.814 +            pgp_key_t key;
  17.815 +            pgp_signature_t selfsig;
  17.816 +            while ((key = pgp_tpk_key_iter_next(key_iter, &selfsig, NULL))) {
  17.817 +                if (! (pgp_signature_can_encrypt_at_rest(selfsig)
  17.818 +                       || pgp_signature_can_encrypt_for_transport(selfsig)))
  17.819                      continue;
  17.820  
  17.821 +                fprintf(stderr, "key: %s\n", pgp_key_debug(key));
  17.822 +
  17.823                  // Note: for decryption to appear to succeed, we must
  17.824                  // get a valid algorithm (8 of 256 values) and a
  17.825                  // 16-bit checksum must match.  Thus, we have about a
  17.826 @@ -951,64 +945,68 @@
  17.827                  uint8_t algo;
  17.828                  uint8_t session_key[1024];
  17.829                  size_t session_key_len = sizeof(session_key);
  17.830 -                if (sq_pkesk_decrypt(cookie->session->ctx, pkesk, key,
  17.831 -                                     &algo, session_key, &session_key_len))
  17.832 +                if (pgp_pkesk_decrypt(&err, pkesk, key,
  17.833 +                                      &algo, session_key, &session_key_len)) {
  17.834 +                    pgp_error_free(err);
  17.835 +                    err = NULL;
  17.836                      continue;
  17.837 +                }
  17.838  
  17.839                  // Add it to the recipient list.
  17.840 -                sq_fingerprint_t fp = sq_tpk_fingerprint(tsk);
  17.841 -                char *fp_string = sq_fingerprint_to_hex(fp);
  17.842 +                pgp_fingerprint_t fp = pgp_tpk_fingerprint(tsk);
  17.843 +                char *fp_string = pgp_fingerprint_to_hex(fp);
  17.844                  T("wildcard recipient appears to be %s", fp_string);
  17.845                  stringlist_add_unique(cookie->recipient_keylist, fp_string);
  17.846                  free(fp_string);
  17.847 -                sq_fingerprint_free(fp);
  17.848 +                pgp_fingerprint_free(fp);
  17.849  
  17.850 -                *secret = sq_secret_cached(algo, session_key, session_key_len);
  17.851 +                *secret = pgp_secret_cached(algo, session_key, session_key_len);
  17.852                  cookie->decrypted = 1;
  17.853 +                break;
  17.854              }
  17.855  
  17.856 -            sq_tpk_key_iter_free(key_iter);
  17.857 +            pgp_tpk_key_iter_free(key_iter);
  17.858              key_iter = NULL;
  17.859          }
  17.860      eol2:
  17.861          free(keyid_str);
  17.862          if (key_iter)
  17.863 -            sq_tpk_key_iter_free(key_iter);
  17.864 +            pgp_tpk_key_iter_free(key_iter);
  17.865      }
  17.866  
  17.867      if (tsks) {
  17.868          for (int i = 0; i < tsks_count; i ++)
  17.869 -            sq_tpk_free(tsks[i]);
  17.870 +            pgp_tpk_free(tsks[i]);
  17.871          free(tsks);
  17.872      }
  17.873  
  17.874 -    return cookie->decrypted ? SQ_STATUS_SUCCESS : SQ_STATUS_UNKNOWN_ERROR;
  17.875 +    return cookie->decrypted ? PGP_STATUS_SUCCESS : PGP_STATUS_UNKNOWN_ERROR;
  17.876  }
  17.877  
  17.878 -static sq_status_t
  17.879 +static pgp_status_t
  17.880  check_signatures_cb(void *cookie_opaque,
  17.881 -                   sq_verification_results_t results, size_t levels)
  17.882 +                   pgp_verification_results_t results, size_t levels)
  17.883  {
  17.884      struct decrypt_cookie *cookie = cookie_opaque;
  17.885      PEP_SESSION session = cookie->session;
  17.886  
  17.887      int level;
  17.888      for (level = 0; level < levels; level ++) {
  17.889 -        sq_verification_result_t *vrs;
  17.890 +        pgp_verification_result_t *vrs;
  17.891          size_t vr_count;
  17.892 -        sq_verification_results_at_level(results, level, &vrs, &vr_count);
  17.893 +        pgp_verification_results_at_level(results, level, &vrs, &vr_count);
  17.894  
  17.895          int i;
  17.896          for (i = 0; i < vr_count; i ++) {
  17.897 -            sq_tpk_t tpk = NULL;
  17.898 -            sq_verification_result_code_t code
  17.899 -                = sq_verification_result_code(vrs[i]);
  17.900 +            pgp_tpk_t tpk = NULL;
  17.901 +            pgp_verification_result_code_t code
  17.902 +                = pgp_verification_result_code(vrs[i]);
  17.903  
  17.904 -            if (code == SQ_VERIFICATION_RESULT_CODE_BAD_CHECKSUM) {
  17.905 +            if (code == PGP_VERIFICATION_RESULT_CODE_BAD_CHECKSUM) {
  17.906                  cookie->bad_checksums ++;
  17.907                  continue;
  17.908              }
  17.909 -            if (code == SQ_VERIFICATION_RESULT_CODE_MISSING_KEY) {
  17.910 +            if (code == PGP_VERIFICATION_RESULT_CODE_MISSING_KEY) {
  17.911                  // No key, nothing we can do.
  17.912                  cookie->missing_keys ++;
  17.913                  continue;
  17.914 @@ -1016,33 +1014,33 @@
  17.915  
  17.916              // We need to add the fingerprint of the primary key to
  17.917              // cookie->signer_keylist.
  17.918 -            sq_signature_t sig = sq_verification_result_signature(vrs[i]);
  17.919 +            pgp_signature_t sig = pgp_verification_result_signature(vrs[i]);
  17.920  
  17.921              // First try looking up by the TPK using the
  17.922              // IssuerFingerprint subpacket.
  17.923 -            sq_fingerprint_t issuer_fp = sq_signature_issuer_fingerprint(sig);
  17.924 +            pgp_fingerprint_t issuer_fp = pgp_signature_issuer_fingerprint(sig);
  17.925              if (issuer_fp) {
  17.926 -                sq_keyid_t issuer = sq_fingerprint_to_keyid(issuer_fp);
  17.927 +                pgp_keyid_t issuer = pgp_fingerprint_to_keyid(issuer_fp);
  17.928                  if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
  17.929                      ; // Soft error.  Ignore.
  17.930 -                sq_keyid_free(issuer);
  17.931 -                sq_fingerprint_free(issuer_fp);
  17.932 +                pgp_keyid_free(issuer);
  17.933 +                pgp_fingerprint_free(issuer_fp);
  17.934              }
  17.935  
  17.936              // If that is not available, try using the Issuer subpacket.
  17.937              if (!tpk) {
  17.938 -                sq_keyid_t issuer = sq_signature_issuer(sig);
  17.939 +                pgp_keyid_t issuer = pgp_signature_issuer(sig);
  17.940                  if (issuer) {
  17.941                      if (tpk_find_by_keyid(session, issuer, false, &tpk, NULL) != PEP_STATUS_OK)
  17.942                          ; // Soft error.  Ignore.
  17.943                  }
  17.944 -                sq_keyid_free(issuer);
  17.945 +                pgp_keyid_free(issuer);
  17.946              }
  17.947  
  17.948              if (tpk) {
  17.949                  // Ok, we have a TPK.
  17.950 -                sq_fingerprint_t fp = sq_tpk_fingerprint(tpk);
  17.951 -                char *fp_str = sq_fingerprint_to_hex(fp);
  17.952 +                pgp_fingerprint_t fp = pgp_tpk_fingerprint(tpk);
  17.953 +                char *fp_str = pgp_fingerprint_to_hex(fp);
  17.954                  stringlist_add_unique(cookie->signer_keylist, fp_str);
  17.955  
  17.956                  // XXX: Check that the TPK and the key used to make
  17.957 @@ -1053,11 +1051,11 @@
  17.958                  cookie->good_checksums ++;
  17.959  
  17.960                  free(fp_str);
  17.961 -                sq_fingerprint_free(fp);
  17.962 -                sq_tpk_free(tpk);
  17.963 +                pgp_fingerprint_free(fp);
  17.964 +                pgp_tpk_free(tpk);
  17.965              } else {
  17.966                  // If we get
  17.967 -                // SQ_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
  17.968 +                // PGP_VERIFICATION_RESULT_CODE_GOOD_CHECKSUM, then the
  17.969                  // TPK should be available.  But, another process
  17.970                  // could have deleted the key from the store in the
  17.971                  // mean time, so be tolerant.
  17.972 @@ -1066,7 +1064,7 @@
  17.973          }
  17.974      }
  17.975  
  17.976 -    return SQ_STATUS_SUCCESS;
  17.977 +    return PGP_STATUS_SUCCESS;
  17.978  }
  17.979  
  17.980  PEP_STATUS pgp_decrypt_and_verify(
  17.981 @@ -1077,8 +1075,9 @@
  17.982  {
  17.983      PEP_STATUS status = PEP_STATUS_OK;
  17.984      struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
  17.985 -    sq_reader_t reader = NULL;
  17.986 -    sq_writer_t writer = NULL;
  17.987 +    pgp_reader_t reader = NULL;
  17.988 +    pgp_writer_t writer = NULL;
  17.989 +    pgp_reader_t decryptor = NULL;
  17.990      *ptext = NULL;
  17.991      *psize = 0;
  17.992  
  17.993 @@ -1088,40 +1087,45 @@
  17.994  
  17.995      cookie.recipient_keylist = new_stringlist(NULL);
  17.996      if (!cookie.recipient_keylist)
  17.997 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "recipient_keylist");
  17.998 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "recipient_keylist");
  17.999  
 17.1000      cookie.signer_keylist = new_stringlist(NULL);
 17.1001      if (!cookie.signer_keylist)
 17.1002 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "signer_keylist");
 17.1003 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "signer_keylist");
 17.1004  
 17.1005 -    reader = sq_reader_from_bytes((const uint8_t *) ctext, csize);
 17.1006 +    reader = pgp_reader_from_bytes((const uint8_t *) ctext, csize);
 17.1007      if (! reader)
 17.1008 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "Creating reader");
 17.1009 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
 17.1010  
 17.1011 -    writer = sq_writer_alloc((void **) ptext, psize);
 17.1012 +    writer = pgp_writer_alloc((void **) ptext, psize);
 17.1013      if (! writer)
 17.1014 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Creating writer");
 17.1015 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "Creating writer");
 17.1016  
 17.1017 -    sq_status_t sq_status = sq_decrypt(session->ctx, reader, writer,
 17.1018 -                                       get_public_keys_cb, get_secret_keys_cb,
 17.1019 -                                       check_signatures_cb, &cookie);
 17.1020 -    if (sq_status)
 17.1021 -        ERROR_OUT(session, PEP_DECRYPT_NO_KEY, "sq_decrypt");
 17.1022 +    pgp_error_t err = NULL;
 17.1023 +    decryptor = pgp_decryptor_new(&err, reader,
 17.1024 +                                  get_public_keys_cb, get_secret_keys_cb,
 17.1025 +                                  check_signatures_cb, &cookie);
 17.1026 +    if (! decryptor)
 17.1027 +        ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "pgp_decryptor_new");
 17.1028 +
 17.1029 +    // Copy 128 MB at a time.
 17.1030 +    ssize_t nread;
 17.1031 +    while ((nread = pgp_reader_copy (&err, decryptor, writer,
 17.1032 +                                     128 * 1024 * 1024) > 0))
 17.1033 +        ;
 17.1034 +    if (nread < 0)
 17.1035 +        ERROR_OUT(err, PGP_STATUS_UNKNOWN_ERROR, "pgp_reader_read");
 17.1036 +
 17.1037 +    // Add a terminating NUL for naive users
 17.1038 +    pgp_writer_write(&err, writer, (const uint8_t *) &""[0], 1);
 17.1039  
 17.1040      if (! cookie.decrypted)
 17.1041 -        ERROR_OUT(session, PEP_DECRYPT_NO_KEY, "Decryption failed");
 17.1042 -
 17.1043 -    // Add a terminating NUL for naive users
 17.1044 -    void *t = realloc(*ptext, *psize + 1);
 17.1045 -    if (! t)
 17.1046 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1047 -    *ptext = t;
 17.1048 -    (*ptext)[*psize] = 0;
 17.1049 +        ERROR_OUT(err, PEP_DECRYPT_NO_KEY, "Decryption failed");
 17.1050  
 17.1051      if (! cookie.signer_keylist) {
 17.1052          cookie.signer_keylist = new_stringlist("");
 17.1053          if (! cookie.signer_keylist)
 17.1054 -            ERROR_OUT(session, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
 17.1055 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
 17.1056      }
 17.1057      if (!cookie.signer_keylist->value)
 17.1058          stringlist_add(cookie.signer_keylist, "");
 17.1059 @@ -1150,9 +1154,11 @@
 17.1060      }
 17.1061  
 17.1062      if (reader)
 17.1063 -        sq_reader_free(reader);
 17.1064 +        pgp_reader_free(reader);
 17.1065 +    if (decryptor)
 17.1066 +        pgp_reader_free(decryptor);
 17.1067      if (writer)
 17.1068 -        sq_writer_free(writer);
 17.1069 +        pgp_writer_free(writer);
 17.1070  
 17.1071      T("-> %s", pep_status_to_string(status));
 17.1072      return status;
 17.1073 @@ -1163,40 +1169,53 @@
 17.1074      const char *signature, size_t sig_size, stringlist_t **keylist)
 17.1075  {
 17.1076      PEP_STATUS status = PEP_STATUS_OK;
 17.1077 +    pgp_error_t err = NULL;
 17.1078      struct decrypt_cookie cookie = { session, 0, NULL, NULL, 0, 0, 0, };
 17.1079 -    sq_reader_t reader = NULL;
 17.1080 -    sq_reader_t dsig_reader = NULL;
 17.1081 +    pgp_reader_t reader = NULL;
 17.1082 +    pgp_reader_t dsig_reader = NULL;
 17.1083 +    pgp_reader_t verifier = NULL;
 17.1084  
 17.1085      if (size == 0 || sig_size == 0)
 17.1086          return PEP_DECRYPT_WRONG_FORMAT;
 17.1087  
 17.1088      cookie.recipient_keylist = new_stringlist(NULL);
 17.1089      if (!cookie.recipient_keylist)
 17.1090 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1091 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
 17.1092  
 17.1093      cookie.signer_keylist = new_stringlist(NULL);
 17.1094      if (!cookie.signer_keylist)
 17.1095 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1096 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
 17.1097  
 17.1098 -    reader = sq_reader_from_bytes((const uint8_t *) text, size);
 17.1099 +    reader = pgp_reader_from_bytes((const uint8_t *) text, size);
 17.1100      if (! reader)
 17.1101 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "Creating reader");
 17.1102 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating reader");
 17.1103  
 17.1104      dsig_reader = NULL;
 17.1105      if (signature) {
 17.1106 -        dsig_reader = sq_reader_from_bytes((uint8_t *) signature, sig_size);
 17.1107 +        dsig_reader = pgp_reader_from_bytes((uint8_t *) signature, sig_size);
 17.1108          if (! dsig_reader)
 17.1109 -            ERROR_OUT(session, PEP_OUT_OF_MEMORY, "Creating signature reader");
 17.1110 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "Creating signature reader");
 17.1111      }
 17.1112  
 17.1113 -    if (sq_verify(session->ctx, reader, dsig_reader, /* output */ NULL,
 17.1114 -                  get_public_keys_cb, check_signatures_cb, &cookie))
 17.1115 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "sq_verify");
 17.1116 +    if (dsig_reader)
 17.1117 +        verifier = pgp_detached_verifier_new(&err, dsig_reader, reader,
 17.1118 +                                             get_public_keys_cb,
 17.1119 +                                             check_signatures_cb,
 17.1120 +                                             &cookie);
 17.1121 +    else
 17.1122 +        verifier = pgp_verifier_new(&err, reader,
 17.1123 +                                    get_public_keys_cb,
 17.1124 +                                    check_signatures_cb,
 17.1125 +                                    &cookie);
 17.1126 +    if (! verifier)
 17.1127 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating verifier");
 17.1128 +    if (pgp_reader_discard(&err, verifier) < 0)
 17.1129 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "verifier");
 17.1130  
 17.1131      if (! cookie.signer_keylist) {
 17.1132          cookie.signer_keylist = new_stringlist("");
 17.1133          if (! cookie.signer_keylist)
 17.1134 -            ERROR_OUT(session, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
 17.1135 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "cookie.signer_keylist");
 17.1136      }
 17.1137      if (!cookie.signer_keylist->value)
 17.1138          stringlist_add(cookie.signer_keylist, "");
 17.1139 @@ -1223,10 +1242,12 @@
 17.1140          free_stringlist(cookie.signer_keylist);
 17.1141      }
 17.1142  
 17.1143 +    if (verifier)
 17.1144 +        pgp_reader_free(verifier);
 17.1145      if (reader)
 17.1146 -        sq_reader_free(reader);
 17.1147 +        pgp_reader_free(reader);
 17.1148      if (dsig_reader)
 17.1149 -        sq_reader_free(dsig_reader);
 17.1150 +        pgp_reader_free(dsig_reader);
 17.1151  
 17.1152      T("-> %s", pep_status_to_string(status));
 17.1153      return status;
 17.1154 @@ -1243,49 +1264,81 @@
 17.1155      assert(psize);
 17.1156      assert(stext);
 17.1157      assert(ssize);
 17.1158 +    *stext = NULL;
 17.1159 +    *ssize = 0;
 17.1160  
 17.1161      PEP_STATUS status = PEP_STATUS_OK;
 17.1162 -    sq_tpk_t signer = NULL;
 17.1163 -    sq_writer_stack_t ws = NULL;
 17.1164 +    pgp_error_t err = NULL;
 17.1165 +    pgp_tpk_t signer_tpk = NULL;
 17.1166 +    pgp_tpk_key_iter_t iter = NULL;
 17.1167 +    pgp_key_pair_t signing_keypair = NULL;
 17.1168 +    pgp_signer_t signer = NULL;
 17.1169 +    pgp_writer_stack_t ws = NULL;
 17.1170  
 17.1171 -    status = tpk_find_by_fpr_hex(session, fpr, true, &signer, NULL);
 17.1172 -    ERROR_OUT(session, status, "Looking up key '%s'", fpr);
 17.1173 +    status = tpk_find_by_fpr_hex(session, fpr, true, &signer_tpk, NULL);
 17.1174 +    ERROR_OUT(NULL, status, "Looking up key '%s'", fpr);
 17.1175  
 17.1176 -    sq_writer_t writer = sq_writer_alloc((void **) stext, ssize);
 17.1177 -    writer = sq_armor_writer_new(session->ctx, writer,
 17.1178 -                                 SQ_ARMOR_KIND_MESSAGE, NULL, 0);
 17.1179 +    iter = pgp_tpk_key_iter_valid(signer_tpk);
 17.1180 +    pgp_tpk_key_iter_signing_capable (iter);
 17.1181 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
 17.1182 +
 17.1183 +    // If there are multiple signing capable subkeys, we just take
 17.1184 +    // the first one, whichever one that happens to be.
 17.1185 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
 17.1186 +    if (! key)
 17.1187 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
 17.1188 +                   "%s has no signing capable key", fpr);
 17.1189 +
 17.1190 +    signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
 17.1191 +    if (! signing_keypair)
 17.1192 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
 17.1193 +
 17.1194 +    signer = pgp_key_pair_as_signer (signing_keypair);
 17.1195 +    if (! signer)
 17.1196 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
 17.1197 +
 17.1198 +
 17.1199 +    pgp_writer_t writer = pgp_writer_alloc((void **) stext, ssize);
 17.1200 +    writer = pgp_armor_writer_new(&err, writer,
 17.1201 +                                  PGP_ARMOR_KIND_MESSAGE, NULL, 0);
 17.1202      if (!writer)
 17.1203 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up armor writer");
 17.1204 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
 17.1205  
 17.1206 -    ws = sq_writer_stack_message(writer);
 17.1207 +    ws = pgp_writer_stack_message(writer);
 17.1208  
 17.1209 -    ws = sq_signer_new_detached(session->ctx, ws, &signer, 1);
 17.1210 +    ws = pgp_signer_new_detached(&err, ws, &signer, 1, 0);
 17.1211      if (!ws)
 17.1212 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up signer");
 17.1213 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
 17.1214  
 17.1215 -    sq_status_t write_status =
 17.1216 -        sq_writer_stack_write_all (session->ctx, ws,
 17.1217 -                                   (uint8_t *) ptext, psize);
 17.1218 +    pgp_status_t write_status =
 17.1219 +        pgp_writer_stack_write_all (&err, ws,
 17.1220 +                                    (uint8_t *) ptext, psize);
 17.1221      if (write_status != 0)
 17.1222 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Encrypting message");
 17.1223 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
 17.1224  
 17.1225      // Add a terminating NUL for naive users
 17.1226      void *t = realloc(*stext, *ssize + 1);
 17.1227      if (! t)
 17.1228 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1229 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
 17.1230      *stext = t;
 17.1231      (*stext)[*ssize] = 0;
 17.1232  
 17.1233   out:
 17.1234      if (ws) {
 17.1235 -        sq_status_t sq_status = sq_writer_stack_finalize (session->ctx, ws);
 17.1236 +        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
 17.1237          ws = NULL;
 17.1238 -        if (sq_status != 0)
 17.1239 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Flushing writer");
 17.1240 +        if (pgp_status != 0)
 17.1241 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
 17.1242      }
 17.1243  
 17.1244      if (signer)
 17.1245 -        sq_tpk_free(signer);
 17.1246 +        pgp_signer_free (signer);
 17.1247 +    if (signing_keypair)
 17.1248 +        pgp_key_pair_free (signing_keypair);
 17.1249 +    if (iter)
 17.1250 +        pgp_tpk_key_iter_free (iter);
 17.1251 +    if (signer_tpk)
 17.1252 +        pgp_tpk_free(signer_tpk);
 17.1253  
 17.1254      T("(%s)-> %s", fpr, pep_status_to_string(status));
 17.1255      return status;
 17.1256 @@ -1296,10 +1349,14 @@
 17.1257      size_t psize, char **ctext, size_t *csize, bool sign)
 17.1258  {
 17.1259      PEP_STATUS status = PEP_STATUS_OK;
 17.1260 +    pgp_error_t err = NULL;
 17.1261      int keys_count = 0;
 17.1262 -    sq_tpk_t *keys = NULL;
 17.1263 -    sq_tpk_t signer = NULL;
 17.1264 -    sq_writer_stack_t ws = NULL;
 17.1265 +    pgp_tpk_t *keys = NULL;
 17.1266 +    pgp_tpk_t signer_tpk = NULL;
 17.1267 +    pgp_writer_stack_t ws = NULL;
 17.1268 +    pgp_tpk_key_iter_t iter = NULL;
 17.1269 +    pgp_key_pair_t signing_keypair = NULL;
 17.1270 +    pgp_signer_t signer = NULL;
 17.1271  
 17.1272      assert(session);
 17.1273      assert(keylist);
 17.1274 @@ -1313,74 +1370,98 @@
 17.1275  
 17.1276      keys = calloc(stringlist_length(keylist), sizeof(*keys));
 17.1277      if (keys == NULL)
 17.1278 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1279 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
 17.1280  
 17.1281      // Get the keys for the recipients.
 17.1282      const stringlist_t *_keylist;
 17.1283      for (_keylist = keylist; _keylist != NULL; _keylist = _keylist->next) {
 17.1284          assert(_keylist->value);
 17.1285 -        sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(_keylist->value);
 17.1286 -        status = tpk_find_by_fpr(session, sq_fpr, false, &keys[keys_count ++], NULL);
 17.1287 -        sq_fingerprint_free(sq_fpr);
 17.1288 -        ERROR_OUT(session, status, "Looking up key for recipient '%s'", _keylist->value);
 17.1289 +        pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(_keylist->value);
 17.1290 +        status = tpk_find_by_fpr(session, pgp_fpr, false, &keys[keys_count ++], NULL);
 17.1291 +        pgp_fingerprint_free(pgp_fpr);
 17.1292 +        ERROR_OUT(NULL, status, "Looking up key for recipient '%s'", _keylist->value);
 17.1293      }
 17.1294  
 17.1295      if (sign) {
 17.1296          // The first key in the keylist is the signer.
 17.1297 -        status = tpk_find_by_fpr_hex(session, keylist->value, true, &signer, NULL);
 17.1298 -        ERROR_OUT(session, status, "Looking up key for signing '%s'", keylist->value);
 17.1299 +        status = tpk_find_by_fpr_hex(session, keylist->value, true, &signer_tpk, NULL);
 17.1300 +        ERROR_OUT(NULL, status, "Looking up key for signing '%s'", keylist->value);
 17.1301      }
 17.1302  
 17.1303 -    sq_writer_t writer = sq_writer_alloc((void **) ctext, csize);
 17.1304 -    writer = sq_armor_writer_new(session->ctx, writer,
 17.1305 -                                 SQ_ARMOR_KIND_MESSAGE, NULL, 0);
 17.1306 +    pgp_writer_t writer = pgp_writer_alloc((void **) ctext, csize);
 17.1307 +    writer = pgp_armor_writer_new(&err, writer,
 17.1308 +                                  PGP_ARMOR_KIND_MESSAGE, NULL, 0);
 17.1309      if (!writer)
 17.1310 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up armor writer");
 17.1311 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up armor writer");
 17.1312  
 17.1313 -    ws = sq_writer_stack_message(writer);
 17.1314 -    ws = sq_encryptor_new (session->ctx, ws,
 17.1315 -                           NULL, 0, keys, keys_count,
 17.1316 -                           SQ_ENCRYPTION_MODE_FOR_TRANSPORT);
 17.1317 -    if (!ws) {
 17.1318 -        sq_writer_free(writer);
 17.1319 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up encryptor");
 17.1320 +    ws = pgp_writer_stack_message(writer);
 17.1321 +    ws = pgp_encryptor_new (&err, ws,
 17.1322 +                            NULL, 0, keys, keys_count,
 17.1323 +                            PGP_ENCRYPTION_MODE_FOR_TRANSPORT, 0);
 17.1324 +    if (!ws)
 17.1325 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up encryptor");
 17.1326 +
 17.1327 +    if (sign) {
 17.1328 +        iter = pgp_tpk_key_iter_valid(signer_tpk);
 17.1329 +        pgp_tpk_key_iter_signing_capable (iter);
 17.1330 +        pgp_tpk_key_iter_unencrypted_secret (iter, true);
 17.1331 +
 17.1332 +        // If there are multiple signing capable subkeys, we just take
 17.1333 +        // the first one, whichever one that happens to be.
 17.1334 +        pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
 17.1335 +        if (! key)
 17.1336 +            ERROR_OUT (err, PEP_UNKNOWN_ERROR,
 17.1337 +                       "%s has no signing capable key", keylist->value);
 17.1338 +
 17.1339 +        signing_keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
 17.1340 +        if (! signing_keypair)
 17.1341 +            ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
 17.1342 +
 17.1343 +        signer = pgp_key_pair_as_signer (signing_keypair);
 17.1344 +        if (! signer)
 17.1345 +            ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
 17.1346 +
 17.1347 +        ws = pgp_signer_new(&err, ws, &signer, 1, 0);
 17.1348 +        if (!ws)
 17.1349 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up signer");
 17.1350      }
 17.1351  
 17.1352 -    if (sign) {
 17.1353 -        ws = sq_signer_new(session->ctx, ws, &signer, 1);
 17.1354 -        if (!ws)
 17.1355 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up signer");
 17.1356 -    }
 17.1357 +    ws = pgp_literal_writer_new (&err, ws);
 17.1358 +    if (!ws)
 17.1359 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Setting up literal writer");
 17.1360  
 17.1361 -    ws = sq_literal_writer_new (session->ctx, ws);
 17.1362 -    if (!ws)
 17.1363 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Setting up literal writer");
 17.1364 -
 17.1365 -    sq_status_t write_status =
 17.1366 -        sq_writer_stack_write_all (session->ctx, ws,
 17.1367 -                                   (uint8_t *) ptext, psize);
 17.1368 +    pgp_status_t write_status =
 17.1369 +        pgp_writer_stack_write_all (&err, ws,
 17.1370 +                                    (uint8_t *) ptext, psize);
 17.1371      if (write_status != 0)
 17.1372 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Encrypting message");
 17.1373 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Encrypting message");
 17.1374  
 17.1375      // Add a terminating NUL for naive users
 17.1376      void *t = realloc(*ctext, *csize + 1);
 17.1377      if (! t)
 17.1378 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "out of memory");
 17.1379 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
 17.1380      *ctext = t;
 17.1381      (*ctext)[*csize] = 0;
 17.1382  
 17.1383   out:
 17.1384      if (ws) {
 17.1385 -        sq_status_t sq_status = sq_writer_stack_finalize (session->ctx, ws);
 17.1386 +        pgp_status_t pgp_status = pgp_writer_stack_finalize (&err, ws);
 17.1387          ws = NULL;
 17.1388 -        if (sq_status != 0)
 17.1389 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Flushing writer");
 17.1390 +        if (pgp_status != 0)
 17.1391 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Flushing writer");
 17.1392      }
 17.1393  
 17.1394      if (signer)
 17.1395 -        sq_tpk_free(signer);
 17.1396 +        pgp_signer_free (signer);
 17.1397 +    if (signing_keypair)
 17.1398 +        pgp_key_pair_free (signing_keypair);
 17.1399 +    if (iter)
 17.1400 +        pgp_tpk_key_iter_free (iter);
 17.1401 +    if (signer_tpk)
 17.1402 +        pgp_tpk_free(signer_tpk);
 17.1403 +
 17.1404      for (int i = 0; i < keys_count; i ++)
 17.1405 -        sq_tpk_free(keys[i]);
 17.1406 +        pgp_tpk_free(keys[i]);
 17.1407      free(keys);
 17.1408  
 17.1409      T("-> %s", pep_status_to_string(status));
 17.1410 @@ -1407,9 +1488,10 @@
 17.1411  PEP_STATUS pgp_generate_keypair(PEP_SESSION session, pEp_identity *identity)
 17.1412  {
 17.1413      PEP_STATUS status = PEP_STATUS_OK;
 17.1414 +    pgp_error_t err = NULL;
 17.1415      char *userid = NULL;
 17.1416 -    sq_tpk_t tpk = NULL;
 17.1417 -    sq_fingerprint_t sq_fpr = NULL;
 17.1418 +    pgp_tpk_t tpk = NULL;
 17.1419 +    pgp_fingerprint_t pgp_fpr = NULL;
 17.1420      char *fpr = NULL;
 17.1421  
 17.1422      assert(session);
 17.1423 @@ -1420,40 +1502,40 @@
 17.1424  
 17.1425      asprintf(&userid, "%s <%s>", identity->username, identity->address);
 17.1426      if (! userid)
 17.1427 -        ERROR_OUT(session, PEP_OUT_OF_MEMORY, "asprintf");
 17.1428 +        ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "asprintf");
 17.1429  
 17.1430      T("(%s)", userid);
 17.1431  
 17.1432      // Generate a key.
 17.1433 -    sq_tsk_t tsk;
 17.1434 -    sq_signature_t rev;
 17.1435 -    if (sq_tsk_new(session->ctx, userid, &tsk, &rev) != 0)
 17.1436 -        ERROR_OUT(session, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
 17.1437 +    pgp_tsk_t tsk;
 17.1438 +    pgp_signature_t rev;
 17.1439 +    if (pgp_tsk_new(&err, userid, &tsk, &rev) != 0)
 17.1440 +        ERROR_OUT(err, PEP_CANNOT_CREATE_KEY, "Generating a key pair");
 17.1441  
 17.1442      // XXX: We should return this.
 17.1443 -    // sq_signature_free(rev);
 17.1444 +    pgp_signature_free(rev);
 17.1445  
 17.1446 -    tpk = sq_tsk_into_tpk(tsk);
 17.1447 +    tpk = pgp_tsk_into_tpk(tsk);
 17.1448  
 17.1449      // Get the fingerprint.
 17.1450 -    sq_fpr = sq_tpk_fingerprint(tpk);
 17.1451 -    fpr = sq_fingerprint_to_hex(sq_fpr);
 17.1452 +    pgp_fpr = pgp_tpk_fingerprint(tpk);
 17.1453 +    fpr = pgp_fingerprint_to_hex(pgp_fpr);
 17.1454  
 17.1455      status = tpk_save(session, tpk, NULL);
 17.1456      tpk = NULL;
 17.1457      if (status != 0)
 17.1458 -        ERROR_OUT(session, PEP_CANNOT_CREATE_KEY, "saving TSK");
 17.1459 +        ERROR_OUT(NULL, PEP_CANNOT_CREATE_KEY, "saving TSK");
 17.1460  
 17.1461      free(identity->fpr);
 17.1462      identity->fpr = fpr;
 17.1463      fpr = NULL;
 17.1464  
 17.1465   out:
 17.1466 -    if (sq_fpr)
 17.1467 -        sq_fingerprint_free(sq_fpr);
 17.1468 +    if (pgp_fpr)
 17.1469 +        pgp_fingerprint_free(pgp_fpr);
 17.1470      free(fpr);
 17.1471      if (tpk)
 17.1472 -        sq_tpk_free(tpk);
 17.1473 +        pgp_tpk_free(tpk);
 17.1474      free(userid);
 17.1475  
 17.1476      T("-> %s", pep_status_to_string(status));
 17.1477 @@ -1463,7 +1545,7 @@
 17.1478  PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
 17.1479  {
 17.1480      PEP_STATUS status = PEP_STATUS_OK;
 17.1481 -    char *fpr = sq_fingerprint_canonicalize(fpr_raw);
 17.1482 +    char *fpr = pgp_fingerprint_canonicalize(fpr_raw);
 17.1483  
 17.1484      T("(%s)", fpr);
 17.1485  
 17.1486 @@ -1483,41 +1565,43 @@
 17.1487                                size_t size, identity_list **private_idents)
 17.1488  {
 17.1489      PEP_STATUS status = PEP_STATUS_OK;
 17.1490 +    pgp_error_t err;
 17.1491  
 17.1492      if (private_idents)
 17.1493          *private_idents = NULL;
 17.1494  
 17.1495      T("parsing %zd bytes", size);
 17.1496  
 17.1497 -    sq_packet_parser_result_t ppr
 17.1498 -        = sq_packet_parser_from_bytes(session->ctx, (uint8_t *) key_data, size);
 17.1499 +    pgp_packet_parser_result_t ppr
 17.1500 +        = pgp_packet_parser_from_bytes(&err, (uint8_t *) key_data, size);
 17.1501      if (! ppr)
 17.1502 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "Creating packet parser");
 17.1503 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "Creating packet parser");
 17.1504  
 17.1505 -    sq_tag_t tag = sq_packet_parser_result_tag(ppr);
 17.1506 +    pgp_tag_t tag = pgp_packet_parser_result_tag(ppr);
 17.1507      switch (tag) {
 17.1508 -    case SQ_TAG_SIGNATURE:
 17.1509 +    case PGP_TAG_SIGNATURE:
 17.1510          // XXX: Implement me.
 17.1511 -        assert(!"Have possible revocation certificate!");
 17.1512 +        // assert(!"Have possible revocation certificate!");
 17.1513 +		ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED, "Implement me: Have possible revocation certificate!");
 17.1514          break;
 17.1515  
 17.1516 -    case SQ_TAG_PUBLIC_KEY:
 17.1517 -    case SQ_TAG_SECRET_KEY: {
 17.1518 -        sq_tpk_t tpk = sq_tpk_from_packet_parser(session->ctx, ppr);
 17.1519 +    case PGP_TAG_PUBLIC_KEY:
 17.1520 +    case PGP_TAG_SECRET_KEY: {
 17.1521 +        pgp_tpk_t tpk = pgp_tpk_from_packet_parser(&err, ppr);
 17.1522          if (! tpk)
 17.1523 -            ERROR_OUT(session, PEP_UNKNOWN_ERROR, "parsing key data");
 17.1524 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "parsing key data");
 17.1525  
 17.1526          // If private_idents is not NULL and there is any private key
 17.1527          // material, it will be saved.
 17.1528          status = tpk_save(session, tpk, private_idents);
 17.1529          if (status == PEP_STATUS_OK)
 17.1530              status = PEP_KEY_IMPORTED;
 17.1531 -        ERROR_OUT(session, status, "saving TPK");
 17.1532 +        ERROR_OUT(NULL, status, "saving TPK");
 17.1533          break;
 17.1534      }
 17.1535      default:
 17.1536 -        ERROR_OUT(session, PEP_NO_KEY_IMPORTED,
 17.1537 -                  "Can't import %s", sq_tag_to_string(tag));        
 17.1538 +        ERROR_OUT(NULL, PEP_NO_KEY_IMPORTED,
 17.1539 +                  "Can't import %s", pgp_tag_to_string(tag));
 17.1540          break;
 17.1541      }
 17.1542  
 17.1543 @@ -1531,8 +1615,9 @@
 17.1544          bool secret)
 17.1545  {
 17.1546      PEP_STATUS status = PEP_STATUS_OK;
 17.1547 -    sq_tpk_t secret_key = NULL;
 17.1548 -    sq_tpk_t tpk = NULL;
 17.1549 +    pgp_error_t err = NULL;
 17.1550 +    pgp_tpk_t tpk = NULL;
 17.1551 +    pgp_writer_t armor_writer = NULL;
 17.1552  
 17.1553      assert(session);
 17.1554      assert(fpr);
 17.1555 @@ -1544,56 +1629,37 @@
 17.1556  
 17.1557      T("(%s, %s)", fpr, secret ? "secret" : "public");
 17.1558  
 17.1559 -    if (secret) {
 17.1560 -        status = tpk_find_by_fpr_hex(session, fpr, true, &secret_key, NULL);
 17.1561 -        if (status == PEP_KEY_NOT_FOUND)
 17.1562 -            status = PEP_STATUS_OK;
 17.1563 -        ERROR_OUT(session, status, "Looking up TSK for %s", fpr);
 17.1564 -    }
 17.1565 +    // If the caller asks for a secret key and we only have a
 17.1566 +    // public key, then we return an error.
 17.1567 +    status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
 17.1568 +    ERROR_OUT(NULL, status, "Looking up TSK for %s", fpr);
 17.1569  
 17.1570 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.1571 -    status = tpk_find_by_fpr(session, sq_fpr, false, &tpk, NULL);
 17.1572 -    sq_fingerprint_free(sq_fpr);
 17.1573 -    ERROR_OUT(session, status, "Looking up TPK for %s", fpr);
 17.1574 -
 17.1575 -    if (secret_key) {
 17.1576 -        tpk = sq_tpk_merge(session->ctx, tpk, secret_key);
 17.1577 -        // sq_tpk_merge can return NULL if the primary keys don't
 17.1578 -        // match.  But, we looked up the tpk by the secret key's
 17.1579 -        // fingerprint so this should not be possible.
 17.1580 -        assert(tpk);
 17.1581 -        secret_key = NULL;
 17.1582 -    }
 17.1583 -
 17.1584 -    sq_writer_t memory_writer = sq_writer_alloc((void **) key_data, size);
 17.1585 +    pgp_writer_t memory_writer = pgp_writer_alloc((void **) key_data, size);
 17.1586      if (! memory_writer)
 17.1587 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "creating memory writer");
 17.1588 -    sq_writer_t armor_writer = sq_armor_writer_new(session->ctx,
 17.1589 -                                                   memory_writer,
 17.1590 -                                                   SQ_ARMOR_KIND_PUBLICKEY,
 17.1591 -                                                   NULL, 0);
 17.1592 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR, "creating memory writer");
 17.1593 +    armor_writer = pgp_armor_writer_new(&err, memory_writer,
 17.1594 +                                        PGP_ARMOR_KIND_PUBLICKEY, NULL, 0);
 17.1595      if (! armor_writer) {
 17.1596 -        sq_writer_free(memory_writer);
 17.1597 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "creating armored writer");
 17.1598 +        pgp_writer_free(memory_writer);
 17.1599 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "creating armored writer");
 17.1600      }
 17.1601  
 17.1602      if (secret) {
 17.1603 -        sq_tsk_t tsk = sq_tpk_into_tsk(tpk);
 17.1604 -        sq_tsk_serialize(session->ctx, tsk, armor_writer);
 17.1605 -        tpk = sq_tsk_into_tpk(tsk);
 17.1606 +        pgp_tsk_t tsk = pgp_tpk_into_tsk(tpk);
 17.1607 +        if (pgp_tsk_serialize(&err, tsk, armor_writer))
 17.1608 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TSK");
 17.1609 +        tpk = pgp_tsk_into_tpk(tsk);
 17.1610      } else {
 17.1611 -        sq_tpk_serialize(session->ctx, tpk, armor_writer);
 17.1612 +        if (pgp_tpk_serialize(&err, tpk, armor_writer))
 17.1613 +            ERROR_OUT(err, PEP_UNKNOWN_ERROR, "serializing TPK");
 17.1614      }
 17.1615  
 17.1616   out:
 17.1617 +    if (armor_writer)
 17.1618 +        pgp_writer_free(armor_writer);
 17.1619 +
 17.1620      if (tpk)
 17.1621 -        sq_tpk_free(tpk);
 17.1622 -
 17.1623 -    if (armor_writer)
 17.1624 -        sq_writer_free(armor_writer);
 17.1625 -
 17.1626 -    if (secret_key)
 17.1627 -        sq_tpk_free(secret_key);
 17.1628 +        pgp_tpk_free(tpk);
 17.1629  
 17.1630      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.1631      return status;
 17.1632 @@ -1632,14 +1698,14 @@
 17.1633  static stringpair_list_t *add_key(PEP_SESSION session,
 17.1634                                    stringpair_list_t *keyinfo_list,
 17.1635                                    stringlist_t* keylist,
 17.1636 -                                  sq_tpk_t tpk, sq_fingerprint_t fpr) {
 17.1637 +                                  pgp_tpk_t tpk, pgp_fingerprint_t fpr) {
 17.1638      bool revoked = false;
 17.1639      // Don't add revoked keys to the keyinfo_list.
 17.1640      if (keyinfo_list) {
 17.1641 -        sq_revocation_status_t rs = sq_tpk_revocation_status(tpk);
 17.1642 -        sq_revocation_status_variant_t rsv = sq_revocation_status_variant(rs);
 17.1643 -        sq_revocation_status_free(rs);
 17.1644 -        if (rsv == SQ_REVOCATION_STATUS_REVOKED)
 17.1645 +        pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
 17.1646 +        pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
 17.1647 +        pgp_revocation_status_free(rs);
 17.1648 +        if (rsv == PGP_REVOCATION_STATUS_REVOKED)
 17.1649              revoked = true;
 17.1650      }
 17.1651  
 17.1652 @@ -1649,12 +1715,12 @@
 17.1653      int dealloc_fpr = 0;
 17.1654      if (!fpr) {
 17.1655          dealloc_fpr = 1;
 17.1656 -        fpr = sq_tpk_fingerprint(tpk);
 17.1657 +        fpr = pgp_tpk_fingerprint(tpk);
 17.1658      }
 17.1659 -    char *fpr_str = sq_fingerprint_to_hex(fpr);
 17.1660 +    char *fpr_str = pgp_fingerprint_to_hex(fpr);
 17.1661  
 17.1662      if (!revoked && keyinfo_list) {
 17.1663 -        char *user_id = sq_tpk_primary_user_id(tpk);
 17.1664 +        char *user_id = pgp_tpk_primary_user_id(tpk);
 17.1665          if (user_id)
 17.1666              keyinfo_list = stringpair_list_add(keyinfo_list,
 17.1667                                                 new_stringpair(fpr_str, user_id));
 17.1668 @@ -1666,7 +1732,7 @@
 17.1669  
 17.1670      free(fpr_str);
 17.1671      if (dealloc_fpr)
 17.1672 -        sq_fingerprint_free(fpr);
 17.1673 +        pgp_fingerprint_free(fpr);
 17.1674  
 17.1675      return keyinfo_list;
 17.1676  }
 17.1677 @@ -1676,8 +1742,8 @@
 17.1678                              stringpair_list_t** keyinfo_list, stringlist_t** keylist)
 17.1679  {
 17.1680      PEP_STATUS status = PEP_STATUS_OK;
 17.1681 -    sq_tpk_t tpk = NULL;
 17.1682 -    sq_fingerprint_t fpr = NULL;
 17.1683 +    pgp_tpk_t tpk = NULL;
 17.1684 +    pgp_fingerprint_t fpr = NULL;
 17.1685  
 17.1686      T("('%s', private: %d)", pattern, private_only);
 17.1687  
 17.1688 @@ -1685,13 +1751,13 @@
 17.1689      if (keyinfo_list) {
 17.1690          _keyinfo_list = new_stringpair_list(NULL);
 17.1691          if (!_keyinfo_list)
 17.1692 -            ERROR_OUT(session, PEP_OUT_OF_MEMORY, "new_stringpair_list");
 17.1693 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_stringpair_list");
 17.1694      }
 17.1695      stringlist_t* _keylist = NULL;
 17.1696      if (keylist) {
 17.1697          _keylist = new_stringlist(NULL);
 17.1698          if (!_keylist)
 17.1699 -            ERROR_OUT(session, PEP_OUT_OF_MEMORY, "new_string_list");
 17.1700 +            ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "new_string_list");
 17.1701      }
 17.1702  
 17.1703      // Trim any leading space.  This also makes it easier to recognize
 17.1704 @@ -1701,13 +1767,13 @@
 17.1705  
 17.1706      if (strchr(pattern, '@')) {
 17.1707          // Looks like a mailbox.
 17.1708 -        sq_tpk_t *tpks = NULL;
 17.1709 +        pgp_tpk_t *tpks = NULL;
 17.1710          int count = 0;
 17.1711          status = tpk_find_by_email(session, pattern, private_only, &tpks, &count);
 17.1712 -        ERROR_OUT(session, status, "Looking up '%s'", pattern);
 17.1713 +        ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
 17.1714          for (int i = 0; i < count; i ++) {
 17.1715              add_key(session, _keyinfo_list, _keylist, tpks[i], NULL);
 17.1716 -            sq_tpk_free(tpks[i]);
 17.1717 +            pgp_tpk_free(tpks[i]);
 17.1718          }
 17.1719          free(tpks);
 17.1720  
 17.1721 @@ -1730,21 +1796,22 @@
 17.1722                 pattern[strspn(pattern, "0123456789aAbBcCdDeEfF ")] == 0
 17.1723                 // And a fair amount of them.
 17.1724                 && strlen(pattern) >= 16) {
 17.1725 -        // Fingerprint.
 17.1726 -        fpr = sq_fingerprint_from_hex(pattern);
 17.1727 +        // Fingerprint.  Note: the pep engine never looks keys up by
 17.1728 +        // keyid, so we don't handle them.
 17.1729 +        fpr = pgp_fingerprint_from_hex(pattern);
 17.1730          status = tpk_find_by_fpr(session, fpr, false, &tpk, NULL);
 17.1731 -        ERROR_OUT(session, status, "Looking up key");
 17.1732 +        ERROR_OUT(NULL, status, "Looking up key");
 17.1733          add_key(session, _keyinfo_list, _keylist, tpk, fpr);
 17.1734      } else if (pattern[0] == 0) {
 17.1735          // Empty string.
 17.1736  
 17.1737 -        sq_tpk_t *tpks = NULL;
 17.1738 +        pgp_tpk_t *tpks = NULL;
 17.1739          int count = 0;
 17.1740          status = tpk_all(session, private_only, &tpks, &count);
 17.1741 -        ERROR_OUT(session, status, "Looking up '%s'", pattern);
 17.1742 +        ERROR_OUT(NULL, status, "Looking up '%s'", pattern);
 17.1743          for (int i = 0; i < count; i ++) {
 17.1744              add_key(session, _keyinfo_list, _keylist, tpks[i], NULL);
 17.1745 -            sq_tpk_free(tpks[i]);
 17.1746 +            pgp_tpk_free(tpks[i]);
 17.1747          }
 17.1748          free(tpks);
 17.1749      } else {
 17.1750 @@ -1753,9 +1820,9 @@
 17.1751  
 17.1752   out:
 17.1753      if (tpk)
 17.1754 -        sq_tpk_free(tpk);
 17.1755 +        pgp_tpk_free(tpk);
 17.1756      if (fpr)
 17.1757 -        sq_fingerprint_free(fpr);
 17.1758 +        pgp_fingerprint_free(fpr);
 17.1759  
 17.1760      if (status == PEP_KEY_NOT_FOUND)
 17.1761          status = PEP_STATUS_OK;
 17.1762 @@ -1826,7 +1893,7 @@
 17.1763      PEP_SESSION session, const char *fpr, PEP_comm_type *comm_type)
 17.1764  {
 17.1765      PEP_STATUS status = PEP_STATUS_OK;
 17.1766 -    sq_tpk_t tpk = NULL;
 17.1767 +    pgp_tpk_t tpk = NULL;
 17.1768  
 17.1769      assert(session);
 17.1770      assert(fpr);
 17.1771 @@ -1834,52 +1901,46 @@
 17.1772  
 17.1773      *comm_type = PEP_ct_unknown;
 17.1774  
 17.1775 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.1776 -    status = tpk_find_by_fpr(session, sq_fpr, false, &tpk, NULL);
 17.1777 -    sq_fingerprint_free(sq_fpr);
 17.1778 -    ERROR_OUT(session, status, "Looking up key: %s", fpr);
 17.1779 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
 17.1780 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
 17.1781 +    pgp_fingerprint_free(pgp_fpr);
 17.1782 +    ERROR_OUT(NULL, status, "Looking up key: %s", fpr);
 17.1783  
 17.1784      *comm_type = PEP_ct_OpenPGP_unconfirmed;
 17.1785  
 17.1786 -    if (sq_tpk_expired(tpk)) {
 17.1787 +    if (pgp_tpk_expired(tpk)) {
 17.1788          *comm_type = PEP_ct_key_expired;
 17.1789          goto out;
 17.1790      }
 17.1791  
 17.1792 -    sq_revocation_status_t rs = sq_tpk_revocation_status(tpk);
 17.1793 -    sq_revocation_status_variant_t rsv = sq_revocation_status_variant(rs);
 17.1794 -    sq_revocation_status_free(rs);
 17.1795 -    if (rsv == SQ_REVOCATION_STATUS_REVOKED) {
 17.1796 +    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
 17.1797 +    pgp_revocation_status_variant_t rsv = pgp_revocation_status_variant(rs);
 17.1798 +    pgp_revocation_status_free(rs);
 17.1799 +    if (rsv == PGP_REVOCATION_STATUS_REVOKED) {
 17.1800          *comm_type = PEP_ct_key_revoked;
 17.1801          goto out;
 17.1802      }
 17.1803  
 17.1804      PEP_comm_type best_enc = PEP_ct_no_encryption, best_sign = PEP_ct_no_encryption;
 17.1805 -    sq_tpk_key_iter_t key_iter = sq_tpk_key_iter(tpk);
 17.1806 -    sq_p_key_t key;
 17.1807 -    sq_signature_t sig;
 17.1808 -    sq_revocation_status_t rev;
 17.1809 -    while ((key = sq_tpk_key_iter_next(key_iter, &sig, &rev))) {
 17.1810 +    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
 17.1811 +    pgp_key_t key;
 17.1812 +    pgp_signature_t sig;
 17.1813 +    pgp_revocation_status_t rev;
 17.1814 +    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
 17.1815          if (! sig)
 17.1816              continue;
 17.1817  
 17.1818 -        if (sq_revocation_status_variant(rev) == SQ_REVOCATION_STATUS_REVOKED)
 17.1819 -            continue;
 17.1820 -
 17.1821 -        if (! sq_p_key_alive(key, sig))
 17.1822 -            continue;
 17.1823 -
 17.1824          PEP_comm_type curr = PEP_ct_no_encryption;
 17.1825  
 17.1826 -        int can_enc = sq_signature_can_encrypt_for_transport(sig)
 17.1827 -            || sq_signature_can_encrypt_at_rest(sig);
 17.1828 -        int can_sign = sq_signature_can_sign(sig);
 17.1829 +        int can_enc = pgp_signature_can_encrypt_for_transport(sig)
 17.1830 +            || pgp_signature_can_encrypt_at_rest(sig);
 17.1831 +        int can_sign = pgp_signature_can_sign(sig);
 17.1832  
 17.1833 -        sq_public_key_algo_t pk_algo = sq_p_key_public_key_algo(key);
 17.1834 -        if (pk_algo == SQ_PUBLIC_KEY_ALGO_RSA_ENCRYPT_SIGN
 17.1835 -            || pk_algo == SQ_PUBLIC_KEY_ALGO_RSA_ENCRYPT
 17.1836 -            || pk_algo == SQ_PUBLIC_KEY_ALGO_RSA_SIGN) {
 17.1837 -            int bits = sq_p_key_public_key_bits(key);
 17.1838 +        pgp_public_key_algo_t pk_algo = pgp_key_public_key_algo(key);
 17.1839 +        if (pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT_SIGN
 17.1840 +            || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_ENCRYPT
 17.1841 +            || pk_algo == PGP_PUBLIC_KEY_ALGO_RSA_SIGN) {
 17.1842 +            int bits = pgp_key_public_key_bits(key);
 17.1843              if (bits < 1024)
 17.1844                  curr = PEP_ct_key_too_short;
 17.1845              else if (bits == 1024)
 17.1846 @@ -1896,7 +1957,7 @@
 17.1847          if (can_sign)
 17.1848              best_sign = _MAX(best_sign, curr);
 17.1849      }
 17.1850 -    sq_tpk_key_iter_free(key_iter);
 17.1851 +    pgp_tpk_key_iter_free(key_iter);
 17.1852  
 17.1853      if (best_enc == PEP_ct_no_encryption || best_sign == PEP_ct_no_encryption) {
 17.1854          *comm_type = PEP_ct_key_b0rken;
 17.1855 @@ -1907,7 +1968,7 @@
 17.1856  
 17.1857   out:
 17.1858      if (tpk)
 17.1859 -        sq_tpk_free(tpk);
 17.1860 +        pgp_tpk_free(tpk);
 17.1861  
 17.1862      T("(%s) -> %s", fpr, pep_comm_type_to_string(*comm_type));
 17.1863      return status;
 17.1864 @@ -1918,32 +1979,63 @@
 17.1865      PEP_SESSION session, const char *fpr, const timestamp *ts)
 17.1866  {
 17.1867      PEP_STATUS status = PEP_STATUS_OK;
 17.1868 -    sq_tpk_t tpk = NULL;
 17.1869 +    pgp_error_t err = NULL;
 17.1870 +    pgp_tpk_t tpk = NULL;
 17.1871 +    pgp_tpk_key_iter_t iter = NULL;
 17.1872 +    pgp_key_pair_t keypair = NULL;
 17.1873 +    pgp_signer_t signer = NULL;
 17.1874      time_t t = mktime((struct tm *) ts);
 17.1875  
 17.1876      T("(%s)", fpr);
 17.1877  
 17.1878      status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
 17.1879 -    ERROR_OUT(session, status, "Looking up '%s'", fpr);
 17.1880 +    ERROR_OUT(NULL, status, "Looking up '%s'", fpr);
 17.1881  
 17.1882 -    uint32_t creation_time = sq_p_key_creation_time(sq_tpk_primary(tpk));
 17.1883 +    uint32_t creation_time = pgp_key_creation_time(pgp_tpk_primary(tpk));
 17.1884      if (creation_time > t)
 17.1885          // The creation time is after the expiration time!
 17.1886 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR,
 17.1887 +        ERROR_OUT(NULL, PEP_UNKNOWN_ERROR,
 17.1888                    "creation time can't be after expiration time");
 17.1889  
 17.1890      uint32_t delta = t - creation_time;
 17.1891 -    tpk = sq_tpk_set_expiry(session->ctx, tpk, delta);
 17.1892 +
 17.1893 +
 17.1894 +    iter = pgp_tpk_key_iter_valid(tpk);
 17.1895 +    pgp_tpk_key_iter_certification_capable (iter);
 17.1896 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
 17.1897 +
 17.1898 +    // If there are multiple certification capable subkeys, we just
 17.1899 +    // take the first one, whichever one that happens to be.
 17.1900 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
 17.1901 +    if (! key)
 17.1902 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
 17.1903 +                   "%s has no usable certification capable key", fpr);
 17.1904 +
 17.1905 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
 17.1906 +    if (! keypair)
 17.1907 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
 17.1908 +
 17.1909 +    signer = pgp_key_pair_as_signer (keypair);
 17.1910 +    if (! signer)
 17.1911 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
 17.1912 +
 17.1913 +    tpk = pgp_tpk_set_expiry(&err, tpk, signer, delta);
 17.1914      if (! tpk)
 17.1915 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "setting expiration");
 17.1916 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
 17.1917  
 17.1918      status = tpk_save(session, tpk, NULL);
 17.1919      tpk = NULL;
 17.1920 -    ERROR_OUT(session, status, "Saving %s", fpr);
 17.1921 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
 17.1922  
 17.1923   out:
 17.1924 +    if (signer)
 17.1925 +        pgp_signer_free (signer);
 17.1926 +    if (keypair)
 17.1927 +        pgp_key_pair_free (keypair);
 17.1928 +    if (iter)
 17.1929 +        pgp_tpk_key_iter_free (iter);
 17.1930      if (tpk)
 17.1931 -        sq_tpk_free(tpk);
 17.1932 +        pgp_tpk_free(tpk);
 17.1933  
 17.1934      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.1935      return status;
 17.1936 @@ -1953,29 +2045,58 @@
 17.1937      PEP_SESSION session, const char *fpr, const char *reason)
 17.1938  {
 17.1939      PEP_STATUS status = PEP_STATUS_OK;
 17.1940 -    sq_tpk_t tpk = NULL;
 17.1941 +    pgp_error_t err = NULL;
 17.1942 +    pgp_tpk_t tpk = NULL;
 17.1943 +    pgp_tpk_key_iter_t iter = NULL;
 17.1944 +    pgp_key_pair_t keypair = NULL;
 17.1945 +    pgp_signer_t signer = NULL;
 17.1946  
 17.1947      T("(%s)", fpr);
 17.1948  
 17.1949      status = tpk_find_by_fpr_hex(session, fpr, true, &tpk, NULL);
 17.1950 -    ERROR_OUT(session, status, "Looking up %s", fpr);
 17.1951 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
 17.1952  
 17.1953 -    tpk = sq_tpk_revoke_in_place(session->ctx, tpk,
 17.1954 -                                 SQ_REASON_FOR_REVOCATION_UNSPECIFIED,
 17.1955 -                                 reason);
 17.1956 +    iter = pgp_tpk_key_iter_valid(tpk);
 17.1957 +    pgp_tpk_key_iter_certification_capable (iter);
 17.1958 +    pgp_tpk_key_iter_unencrypted_secret (iter, true);
 17.1959 +
 17.1960 +    // If there are multiple certification capable subkeys, we just
 17.1961 +    // take the first one, whichever one that happens to be.
 17.1962 +    pgp_key_t key = pgp_tpk_key_iter_next (iter, NULL, NULL);
 17.1963 +    if (! key)
 17.1964 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR,
 17.1965 +                   "%s has no usable certification capable key", fpr);
 17.1966 +
 17.1967 +    keypair = pgp_key_into_key_pair (NULL, pgp_key_clone (key));
 17.1968 +    if (! keypair)
 17.1969 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a keypair");
 17.1970 +
 17.1971 +    signer = pgp_key_pair_as_signer (keypair);
 17.1972 +    if (! signer)
 17.1973 +        ERROR_OUT (err, PEP_UNKNOWN_ERROR, "Creating a signer");
 17.1974 +
 17.1975 +    tpk = pgp_tpk_revoke_in_place(&err, tpk, signer,
 17.1976 +                                  PGP_REASON_FOR_REVOCATION_UNSPECIFIED,
 17.1977 +                                  reason);
 17.1978      if (! tpk)
 17.1979 -        ERROR_OUT(session, PEP_UNKNOWN_ERROR, "setting expiration");
 17.1980 +        ERROR_OUT(err, PEP_UNKNOWN_ERROR, "setting expiration");
 17.1981  
 17.1982 -    assert(sq_revocation_status_variant(sq_tpk_revocation_status(tpk))
 17.1983 -           == SQ_REVOCATION_STATUS_REVOKED);
 17.1984 +    assert(pgp_revocation_status_variant(pgp_tpk_revocation_status(tpk))
 17.1985 +           == PGP_REVOCATION_STATUS_REVOKED);
 17.1986  
 17.1987      status = tpk_save(session, tpk, NULL);
 17.1988      tpk = NULL;
 17.1989 -    ERROR_OUT(session, status, "Saving %s", fpr);
 17.1990 +    ERROR_OUT(NULL, status, "Saving %s", fpr);
 17.1991  
 17.1992   out:
 17.1993 +    if (signer)
 17.1994 +        pgp_signer_free (signer);
 17.1995 +    if (keypair)
 17.1996 +        pgp_key_pair_free (keypair);
 17.1997 +    if (iter)
 17.1998 +        pgp_tpk_key_iter_free (iter);
 17.1999      if (tpk)
 17.2000 -        sq_tpk_free(tpk);
 17.2001 +        pgp_tpk_free(tpk);
 17.2002  
 17.2003      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.2004      return status;
 17.2005 @@ -1985,7 +2106,7 @@
 17.2006                             const time_t when, bool *expired)
 17.2007  {
 17.2008      PEP_STATUS status = PEP_STATUS_OK;
 17.2009 -    sq_tpk_t tpk = NULL;
 17.2010 +    pgp_tpk_t tpk = NULL;
 17.2011      T("(%s)", fpr);
 17.2012  
 17.2013      assert(session);
 17.2014 @@ -1994,13 +2115,13 @@
 17.2015  
 17.2016      *expired = false;
 17.2017  
 17.2018 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.2019 -    status = tpk_find_by_fpr(session, sq_fpr, false, &tpk, NULL);
 17.2020 -    sq_fingerprint_free(sq_fpr);
 17.2021 -    ERROR_OUT(session, status, "Looking up %s", fpr);
 17.2022 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
 17.2023 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
 17.2024 +    pgp_fingerprint_free(pgp_fpr);
 17.2025 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
 17.2026  
 17.2027      // Is the TPK live?
 17.2028 -    *expired = !sq_tpk_alive_at(tpk, when);
 17.2029 +    *expired = !pgp_tpk_alive_at(tpk, when);
 17.2030      if (*expired)
 17.2031          goto out;
 17.2032  
 17.2033 @@ -2008,38 +2129,32 @@
 17.2034      // and one encryption subkey that are live?
 17.2035      int can_certify = 0, can_encrypt = 0, can_sign = 0;
 17.2036  
 17.2037 -    sq_tpk_key_iter_t key_iter = sq_tpk_key_iter(tpk);
 17.2038 -    sq_p_key_t key;
 17.2039 -    sq_signature_t sig;
 17.2040 -    sq_revocation_status_t rev;
 17.2041 -    while ((key = sq_tpk_key_iter_next(key_iter, &sig, &rev))) {
 17.2042 +    pgp_tpk_key_iter_t key_iter = pgp_tpk_key_iter_valid(tpk);
 17.2043 +    pgp_key_t key;
 17.2044 +    pgp_signature_t sig;
 17.2045 +    pgp_revocation_status_t rev;
 17.2046 +    while ((key = pgp_tpk_key_iter_next(key_iter, &sig, &rev))) {
 17.2047          if (! sig)
 17.2048              continue;
 17.2049  
 17.2050 -        if (sq_revocation_status_variant(rev) == SQ_REVOCATION_STATUS_REVOKED)
 17.2051 -            continue;
 17.2052 -
 17.2053 -        if (!sq_p_key_alive_at(key, sig, when))
 17.2054 -            continue;
 17.2055 -
 17.2056 -        if (sq_signature_can_encrypt_for_transport(sig)
 17.2057 -            || sq_signature_can_encrypt_at_rest(sig))
 17.2058 +        if (pgp_signature_can_encrypt_for_transport(sig)
 17.2059 +            || pgp_signature_can_encrypt_at_rest(sig))
 17.2060              can_encrypt = 1;
 17.2061 -        if (sq_signature_can_sign(sig))
 17.2062 +        if (pgp_signature_can_sign(sig))
 17.2063              can_sign = 1;
 17.2064 -        if (sq_signature_can_certify(sig))
 17.2065 +        if (pgp_signature_can_certify(sig))
 17.2066              can_certify = 1;
 17.2067  
 17.2068          if (can_encrypt && can_sign && can_certify)
 17.2069              break;
 17.2070      }
 17.2071 -    sq_tpk_key_iter_free(key_iter);
 17.2072 +    pgp_tpk_key_iter_free(key_iter);
 17.2073  
 17.2074      *expired = !(can_encrypt && can_sign && can_certify);
 17.2075  
 17.2076   out:
 17.2077      if (tpk)
 17.2078 -        sq_tpk_free(tpk);
 17.2079 +        pgp_tpk_free(tpk);
 17.2080      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.2081      return status;
 17.2082  }
 17.2083 @@ -2047,7 +2162,7 @@
 17.2084  PEP_STATUS pgp_key_revoked(PEP_SESSION session, const char *fpr, bool *revoked)
 17.2085  {
 17.2086      PEP_STATUS status = PEP_STATUS_OK;
 17.2087 -    sq_tpk_t tpk;
 17.2088 +    pgp_tpk_t tpk;
 17.2089  
 17.2090      T("(%s)", fpr);
 17.2091  
 17.2092 @@ -2057,15 +2172,15 @@
 17.2093  
 17.2094      *revoked = false;
 17.2095  
 17.2096 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.2097 -    status = tpk_find_by_fpr(session, sq_fpr, false, &tpk, NULL);
 17.2098 -    sq_fingerprint_free(sq_fpr);
 17.2099 -    ERROR_OUT(session, status, "Looking up %s", fpr);
 17.2100 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
 17.2101 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
 17.2102 +    pgp_fingerprint_free(pgp_fpr);
 17.2103 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
 17.2104  
 17.2105 -    sq_revocation_status_t rs = sq_tpk_revocation_status(tpk);
 17.2106 -    *revoked = sq_revocation_status_variant(rs) == SQ_REVOCATION_STATUS_REVOKED;
 17.2107 -    sq_revocation_status_free (rs);
 17.2108 -    sq_tpk_free(tpk);
 17.2109 +    pgp_revocation_status_t rs = pgp_tpk_revocation_status(tpk);
 17.2110 +    *revoked = pgp_revocation_status_variant(rs) == PGP_REVOCATION_STATUS_REVOKED;
 17.2111 +    pgp_revocation_status_free (rs);
 17.2112 +    pgp_tpk_free(tpk);
 17.2113  
 17.2114   out:
 17.2115      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.2116 @@ -2075,19 +2190,19 @@
 17.2117  PEP_STATUS pgp_key_created(PEP_SESSION session, const char *fpr, time_t *created)
 17.2118  {
 17.2119      PEP_STATUS status = PEP_STATUS_OK;
 17.2120 -    sq_tpk_t tpk = NULL;
 17.2121 +    pgp_tpk_t tpk = NULL;
 17.2122      T("(%s)", fpr);
 17.2123  
 17.2124      *created = 0;
 17.2125  
 17.2126 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.2127 -    status = tpk_find_by_fpr(session, sq_fpr, false, &tpk, NULL);
 17.2128 -    sq_fingerprint_free(sq_fpr);
 17.2129 -    ERROR_OUT(session, status, "Looking up %s", fpr);
 17.2130 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
 17.2131 +    status = tpk_find_by_fpr(session, pgp_fpr, false, &tpk, NULL);
 17.2132 +    pgp_fingerprint_free(pgp_fpr);
 17.2133 +    ERROR_OUT(NULL, status, "Looking up %s", fpr);
 17.2134  
 17.2135 -    sq_p_key_t k = sq_tpk_primary(tpk);
 17.2136 -    *created = sq_p_key_creation_time(k);
 17.2137 -    sq_tpk_free(tpk);
 17.2138 +    pgp_key_t k = pgp_tpk_primary(tpk);
 17.2139 +    *created = pgp_key_creation_time(k);
 17.2140 +    pgp_tpk_free(tpk);
 17.2141  
 17.2142   out:
 17.2143      T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.2144 @@ -2096,6 +2211,7 @@
 17.2145  
 17.2146  PEP_STATUS pgp_binary(const char **path)
 17.2147  {
 17.2148 +    *path = NULL;
 17.2149      return PEP_STATUS_OK;
 17.2150  }
 17.2151  
 17.2152 @@ -2103,15 +2219,16 @@
 17.2153                                   bool *has_private)
 17.2154  {
 17.2155      T("(%s)", fpr);
 17.2156 -    sq_fingerprint_t sq_fpr = sq_fingerprint_from_hex(fpr);
 17.2157 -    PEP_STATUS status = tpk_find_by_fpr(session, sq_fpr, true, NULL, NULL);
 17.2158 -    sq_fingerprint_free(sq_fpr);
 17.2159 +    pgp_fingerprint_t pgp_fpr = pgp_fingerprint_from_hex(fpr);
 17.2160 +    PEP_STATUS status = tpk_find_by_fpr(session, pgp_fpr, true, NULL, NULL);
 17.2161 +    pgp_fingerprint_free(pgp_fpr);
 17.2162      if (status == PEP_STATUS_OK) {
 17.2163          *has_private = 1;
 17.2164      } else if (status == PEP_KEY_NOT_FOUND) {
 17.2165          *has_private = 0;
 17.2166          status = PEP_STATUS_OK;
 17.2167      }
 17.2168 -    T("(%s) -> %s", fpr, pep_status_to_string(status));
 17.2169 +    T("(%s) -> %s, %s",
 17.2170 +      fpr, *has_private ? "priv" : "pub", pep_status_to_string(status));
 17.2171      return status;
 17.2172  }
    18.1 --- a/src/pgp_sequoia_internal.h	Thu Feb 07 16:02:11 2019 +0100
    18.2 +++ b/src/pgp_sequoia_internal.h	Mon Apr 01 20:58:40 2019 +0200
    18.3 @@ -3,4 +3,4 @@
    18.4  
    18.5  #pragma once
    18.6  
    18.7 -#include <sequoia.h>
    18.8 +#include <sequoia/openpgp.h>
    19.1 --- a/src/stringlist.c	Thu Feb 07 16:02:11 2019 +0100
    19.2 +++ b/src/stringlist.c	Mon Apr 01 20:58:40 2019 +0200
    19.3 @@ -229,6 +229,50 @@
    19.4      return stringlist;
    19.5  }
    19.6  
    19.7 +static stringlist_t* stringlist_multi_delete(stringlist_t* stringlist, const char* value) {
    19.8 +    if (stringlist == NULL || !stringlist->value)
    19.9 +        return stringlist;
   19.10 +    
   19.11 +    stringlist_t* list_curr = stringlist;
   19.12 +    stringlist_t* prev_ptr = NULL;
   19.13 +    
   19.14 +    while (list_curr) {
   19.15 +        if (strcmp(list_curr->value, value) == 0) {
   19.16 +            stringlist_t* victim = list_curr;
   19.17 +            if (prev_ptr)
   19.18 +                prev_ptr->next = list_curr->next;    
   19.19 +            else
   19.20 +                stringlist = list_curr->next;
   19.21 +            
   19.22 +            list_curr = list_curr->next;
   19.23 +
   19.24 +            victim->next = NULL;
   19.25 +            
   19.26 +            free_stringlist(victim);
   19.27 +        }
   19.28 +        else {
   19.29 +            prev_ptr = list_curr;
   19.30 +            list_curr = list_curr->next;
   19.31 +        }
   19.32 +    }
   19.33 +    return stringlist;
   19.34 +}
   19.35 +
   19.36 +
   19.37 +
   19.38 +void dedup_stringlist(stringlist_t* stringlist) {
   19.39 +    if (stringlist == NULL || !stringlist->value)
   19.40 +        return;
   19.41 +        
   19.42 +    stringlist_t* list_curr = stringlist;
   19.43 +
   19.44 +    while (list_curr && list_curr->next) {
   19.45 +        stringlist_t* new_next = stringlist_multi_delete(list_curr->next, list_curr->value);
   19.46 +        list_curr->next = new_next;
   19.47 +        list_curr = list_curr->next;
   19.48 +    }    
   19.49 +}
   19.50 +
   19.51  DYNAMIC_API void free_stringlist(stringlist_t *stringlist)
   19.52  {
   19.53      stringlist_t *curr = stringlist;
    20.1 --- a/src/stringlist.h	Thu Feb 07 16:02:11 2019 +0100
    20.2 +++ b/src/stringlist.h	Mon Apr 01 20:58:40 2019 +0200
    20.3 @@ -135,7 +135,8 @@
    20.4  
    20.5  stringlist_t* stringlist_search(stringlist_t* head, const char* value);
    20.6  
    20.7 +void dedup_stringlist(stringlist_t* stringlist);
    20.8 +
    20.9  #ifdef __cplusplus
   20.10  }
   20.11  #endif
   20.12 -
    21.1 --- a/src/sync_api.c	Thu Feb 07 16:02:11 2019 +0100
    21.2 +++ b/src/sync_api.c	Mon Apr 01 20:58:40 2019 +0200
    21.3 @@ -39,18 +39,23 @@
    21.4  
    21.5  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
    21.6          PEP_SESSION session,
    21.7 -        pEp_identity *partner,
    21.8 -        sync_handshake_result result
    21.9 +        sync_handshake_result result,
   21.10 +        const identity_list *identities_sharing
   21.11      )
   21.12  {
   21.13      assert(session);
   21.14      if (!session)
   21.15          return PEP_ILLEGAL_VALUE;
   21.16  
   21.17 +    for (const identity_list *_il = identities_sharing; _il && _il->ident;
   21.18 +            _il = _il->next) {
   21.19 +        if (!_il->ident->me || !_il->ident->user_id || !_il->ident->user_id[0]
   21.20 +                || !_il->ident->address || !_il->ident->address[0])
   21.21 +            return PEP_ILLEGAL_VALUE;
   21.22 +    }
   21.23 +
   21.24      PEP_STATUS status = PEP_STATUS_OK;
   21.25 -
   21.26      int event;
   21.27 -    bool need_partner = false;
   21.28  
   21.29      switch (result) {
   21.30          case SYNC_HANDSHAKE_CANCEL:
   21.31 @@ -70,14 +75,20 @@
   21.32              return PEP_ILLEGAL_VALUE;
   21.33      }
   21.34  
   21.35 -    pEp_identity *_partner = NULL;
   21.36 -    if(need_partner){
   21.37 -        _partner = identity_dup(partner);
   21.38 -        if (_partner == NULL)
   21.39 -            return PEP_OUT_OF_MEMORY;
   21.40 +    free_identity_list(session->sync_state.common.own_identities);
   21.41 +    session->sync_state.common.own_identities = NULL;
   21.42 +
   21.43 +    if (identities_sharing && identities_sharing->ident) {
   21.44 +        session->sync_state.common.own_identities = identity_list_dup(identities_sharing);
   21.45 +        if (!session->sync_state.common.own_identities)
   21.46 +            status = PEP_OUT_OF_MEMORY;
   21.47      }
   21.48 -    status = send_Sync_message(session, Sync_PR_keysync, event);
   21.49 +    else {
   21.50 +        status = own_identities_retrieve(session, &session->sync_state.common.own_identities);
   21.51 +    }
   21.52  
   21.53 +    if (!status)
   21.54 +        status = signal_Sync_event(session, Sync_PR_keysync, event);
   21.55      return status;
   21.56  }
   21.57  
   21.58 @@ -128,14 +139,6 @@
   21.59      session->sync_obj = obj;
   21.60  
   21.61      PEP_STATUS status = recv_Sync_event(session, event);
   21.62 -    if (status != PEP_STATUS_OK && status != PEP_MESSAGE_IGNORE) {
   21.63 -        char buffer[MAX_LINELENGTH];
   21.64 -        memset(buffer, 0, MAX_LINELENGTH);
   21.65 -        snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n",
   21.66 -                (int) status);
   21.67 -        log_event(session, buffer, "pEp sync protocol", NULL, NULL);
   21.68 -    }
   21.69 -
   21.70      return status == PEP_MESSAGE_IGNORE ? PEP_STATUS_OK : status;
   21.71  }
   21.72  
   21.73 @@ -152,3 +155,86 @@
   21.74      return SYNC_TIMEOUT_EVENT;
   21.75  }
   21.76  
   21.77 +DYNAMIC_API PEP_STATUS enter_device_group(
   21.78 +        PEP_SESSION session,
   21.79 +        const identity_list *identities_sharing
   21.80 +    )
   21.81 +{
   21.82 +    assert(session);
   21.83 +    if (!session)
   21.84 +        return PEP_ILLEGAL_VALUE;
   21.85 +
   21.86 +    for (const identity_list *_il = identities_sharing; _il && _il->ident;
   21.87 +            _il = _il->next) {
   21.88 +        if (!_il->ident->me || !_il->ident->user_id || !_il->ident->user_id[0]
   21.89 +                || !_il->ident->address || !_il->ident->address[0])
   21.90 +            return PEP_ILLEGAL_VALUE;
   21.91 +    }
   21.92 +
   21.93 +    identity_list *own_identities = NULL;
   21.94 +    PEP_STATUS status = own_identities_retrieve(session, &own_identities);
   21.95 +    if (status)
   21.96 +        goto the_end;
   21.97 +
   21.98 +    if (identities_sharing && identities_sharing->ident) {
   21.99 +        for (identity_list *_il = own_identities; _il && _il->ident;
  21.100 +                _il = _il->next) {
  21.101 +            bool found = false;
  21.102 +
  21.103 +            for (const identity_list *_is = identities_sharing;
  21.104 +                    _is && _is->ident; _is = _is->next) {
  21.105 +                // FIXME: "john@doe.com" and "mailto:john@doe.com" should be equal
  21.106 +                if (strcmp(_il->ident->address, _is->ident->address) == 0
  21.107 +                        && strcmp(_il->ident->user_id, _is->ident->user_id) == 0) {
  21.108 +                    found = true;
  21.109 +
  21.110 +                    status = set_identity_flags(session, _il->ident, PEP_idf_devicegroup);
  21.111 +                    if (status)
  21.112 +                        goto the_end;
  21.113 +
  21.114 +                    break;
  21.115 +                }
  21.116 +            }
  21.117 +            if (!found) {
  21.118 +                status = unset_identity_flags(session, _il->ident, PEP_idf_devicegroup);
  21.119 +                if (status)
  21.120 +                    goto the_end;
  21.121 +            }
  21.122 +        }
  21.123 +    }
  21.124 +    else {
  21.125 +        for (identity_list *_il = own_identities; _il && _il->ident;
  21.126 +                _il = _il->next) {
  21.127 +            status = set_identity_flags(session, _il->ident, PEP_idf_devicegroup);
  21.128 +            if (status)
  21.129 +                goto the_end;
  21.130 +        }
  21.131 +    }
  21.132 +
  21.133 +the_end:
  21.134 +    free_identity_list(own_identities);
  21.135 +    return status;
  21.136 +}
  21.137 +
  21.138 +DYNAMIC_API PEP_STATUS leave_device_group(PEP_SESSION session)
  21.139 +{
  21.140 +    assert(session);
  21.141 +    if (!session)
  21.142 +        return PEP_ILLEGAL_VALUE;
  21.143 +
  21.144 +    identity_list *il = NULL;
  21.145 +    PEP_STATUS status = own_identities_retrieve(session, &il);
  21.146 +    if (status)
  21.147 +        goto the_end;
  21.148 +
  21.149 +    for (identity_list *_il = il; _il && _il->ident ; _il = _il->next) {
  21.150 +        status = unset_identity_flags(session, _il->ident, PEP_idf_devicegroup);
  21.151 +        if (status)
  21.152 +            goto the_end;
  21.153 +    }
  21.154 +
  21.155 +the_end:
  21.156 +    free_identity_list(il);
  21.157 +    return status;
  21.158 +}
  21.159 +
    22.1 --- a/src/sync_api.h	Thu Feb 07 16:02:11 2019 +0100
    22.2 +++ b/src/sync_api.h	Mon Apr 01 20:58:40 2019 +0200
    22.3 @@ -60,16 +60,22 @@
    22.4      SYNC_HANDSHAKE_REJECTED = 1
    22.5  } sync_handshake_result;
    22.6  
    22.7 -// deliverHandshakeResult() - give the result of the handshake dialog
    22.8 +// deliverHandshakeResult() - provide the result of the handshake dialog
    22.9  //
   22.10  //  parameters:
   22.11 -//      session (in)        session handle
   22.12 -//      result (in)         handshake result
   22.13 +//      session (in)            session handle
   22.14 +//      result (in)             handshake result
   22.15 +//      identities_sharing (in) own_identities sharing data in this group
   22.16 +//
   22.17 +//  caveat:
   22.18 +//      identities_sharing may be NULL; in this case all identities are sharing
   22.19 +//      data in the group
   22.20 +//      identities_sharing may only contain own identities
   22.21  
   22.22  DYNAMIC_API PEP_STATUS deliverHandshakeResult(
   22.23          PEP_SESSION session,
   22.24 -        pEp_identity *partner,
   22.25 -        sync_handshake_result result
   22.26 +        sync_handshake_result result,
   22.27 +        const identity_list *identities_sharing
   22.28      );
   22.29  
   22.30  
   22.31 @@ -153,7 +159,7 @@
   22.32  // is_sync_thread() - determine if this is sync thread's session
   22.33  //
   22.34  //  paramters:
   22.35 -//      session                 pEp session to test
   22.36 +//      session (in)            pEp session to test
   22.37  //
   22.38  //  return value:
   22.39  //      true if this is sync thread's session, false otherwise
   22.40 @@ -169,6 +175,33 @@
   22.41  DYNAMIC_API SYNC_EVENT new_sync_timeout_event();
   22.42  
   22.43  
   22.44 +// enter_device_group() - enter a device group
   22.45 +//
   22.46 +//  parameters:
   22.47 +//      session (in)            pEp session
   22.48 +//      identities_sharing (in) own_identities sharing data in this group
   22.49 +//
   22.50 +//  caveat:
   22.51 +//      identities_sharing may be NULL; in this case all identities are sharing
   22.52 +//      data in the group
   22.53 +//      identities_sharing may only contain own identities
   22.54 +//
   22.55 +//      this call can be repeated if sharing information changes
   22.56 +
   22.57 +DYNAMIC_API PEP_STATUS enter_device_group(
   22.58 +        PEP_SESSION session,
   22.59 +        const identity_list *identities_sharing
   22.60 +    );
   22.61 +
   22.62 +
   22.63 +// leave_device_group() - leave a device group
   22.64 +//
   22.65 +//  parameters:
   22.66 +//      session                 pEp session
   22.67 +
   22.68 +DYNAMIC_API PEP_STATUS leave_device_group(PEP_SESSION session);
   22.69 +
   22.70 +
   22.71  #ifdef __cplusplus
   22.72  }
   22.73  #endif
    23.1 --- a/sync/cond_act_sync.yml2	Thu Feb 07 16:02:11 2019 +0100
    23.2 +++ b/sync/cond_act_sync.yml2	Mon Apr 01 20:58:40 2019 +0200
    23.3 @@ -40,11 +40,12 @@
    23.4  condition keyElectionWon
    23.5  ||
    23.6      pEp_identity *from = session->sync_state.common.from;
    23.7 +    char *signature_fpr = session->sync_state.common.signature_fpr;
    23.8  
    23.9 -    assert(from && from->fpr && from->fpr[0] && from->address &&
   23.10 -            from->address[0] && from->user_id && from->user_id[0]);
   23.11 -    if (!(from && from->fpr && from->fpr[0] && from->address &&
   23.12 -            from->address[0] && from->user_id && from->user_id[0]))
   23.13 +    assert(from && from->address && from->address[0] && from->user_id &&
   23.14 +            from->user_id[0]);
   23.15 +    if (!(from && from->address && from->address[0] && from->user_id &&
   23.16 +            from->user_id[0]))
   23.17          return PEP_ILLEGAL_VALUE;
   23.18  
   23.19      pEp_identity *me = NULL;
   23.20 @@ -59,8 +60,8 @@
   23.21          return PEP_ILLEGAL_VALUE;
   23.22      }
   23.23  
   23.24 -    size_t len = MIN(strlen(from->fpr), strlen(me->fpr));
   23.25 -    *result = strncasecmp(from->fpr, me->fpr, len) > 0;
   23.26 +    size_t len = MIN(strlen(signature_fpr), strlen(me->fpr));
   23.27 +    *result = strncasecmp(signature_fpr, me->fpr, len) > 0;
   23.28      free_identity(me);
   23.29  ||
   23.30  
   23.31 @@ -136,6 +137,17 @@
   23.32              return PEP_OUT_OF_MEMORY;
   23.33          }
   23.34  
   23.35 +        assert(session->sync_state.common.signature_fpr);
   23.36 +        if (session->sync_state.common.signature_fpr) {
   23.37 +            free(partner->fpr);
   23.38 +            partner->fpr = strdup(session->sync_state.common.signature_fpr);
   23.39 +            if (!partner->fpr) {
   23.40 +                free_identity(me);
   23.41 +                free_identity(partner);
   23.42 +                return PEP_OUT_OF_MEMORY;
   23.43 +            }
   23.44 +        }
   23.45 +
   23.46          status = session->notifyHandshake(me, partner, «$type»);
   23.47          if (status)
   23.48              return status;
   23.49 @@ -154,9 +166,28 @@
   23.50  timeout KeySync
   23.51      call "show_handshake" with "type" > SYNC_NOTIFY_TIMEOUT
   23.52  
   23.53 +action prepareOwnKeys
   23.54 +||
   23.55 +    stringlist_t *own_keys;
   23.56 +    PEP_STATUS status = _own_keys_retrieve(session, &own_keys, PEP_idf_not_for_sync);
   23.57 +    if (status)
   23.58 +        return status;
   23.59 +
   23.60 +    if (session->sync_state.common.own_keys)
   23.61 +        free_stringlist(session->sync_state.common.own_keys);
   23.62 +    session->sync_state.common.own_keys = own_keys;
   23.63 +
   23.64 +    identity_list *il;
   23.65 +    status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
   23.66 +    if (status)
   23.67 +        return status;
   23.68 +
   23.69 +    IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
   23.70 +||
   23.71 +
   23.72  action saveGroupKeys
   23.73  ||
   23.74 -    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.identities, NULL);
   23.75 +    identity_list *il = IdentityList_to_identity_list(&session->sync_state.keysync.ownIdentities, NULL);
   23.76      if (!il)
   23.77          return PEP_OUT_OF_MEMORY;
   23.78      
   23.79 @@ -242,12 +273,14 @@
   23.80              }
   23.81          } while (result != SQLITE_DONE);
   23.82  
   23.83 -        IdentityList_t *r = IdentityList_from_identity_list(il, &session->sync_state.keysync.identities);
   23.84 +        IdentityList_t *r = IdentityList_from_identity_list(il, &session->sync_state.keysync.ownIdentities);
   23.85          free_identity_list(il);
   23.86          if (!r)
   23.87              return PEP_OUT_OF_MEMORY;
   23.88      ||
   23.89  }
   23.90  
   23.91 +action receivedKeysAreGroupKeys;
   23.92 +
   23.93  action disable;
   23.94  
    24.1 --- a/sync/gen_message_func.ysl2	Thu Feb 07 16:02:11 2019 +0100
    24.2 +++ b/sync/gen_message_func.ysl2	Mon Apr 01 20:58:40 2019 +0200
    24.3 @@ -41,6 +41,9 @@
    24.4  struct «@name»_state_s {
    24.5      struct common_state_s {
    24.6          pEp_identity *from;
    24.7 +        char *signature_fpr;
    24.8 +        stringlist_t *own_keys;
    24.9 +        identity_list *own_identities;
   24.10      } common;
   24.11  
   24.12      `` apply "fsm", mode=state
   24.13 @@ -96,6 +99,9 @@
   24.14          return;
   24.15  
   24.16      free_identity(session->«yml:lcase(@name)»_state.common.from);
   24.17 +    free(session->«yml:lcase(@name)»_state.common.signature_fpr);
   24.18 +    free_stringlist(session->«yml:lcase(@name)»_state.common.own_keys);
   24.19 +    free_identity_list(session->«yml:lcase(@name)»_state.common.own_identities);
   24.20  
   24.21  ||
   24.22  for "fsm"
    25.1 --- a/sync/gen_statemachine.ysl2	Thu Feb 07 16:02:11 2019 +0100
    25.2 +++ b/sync/gen_statemachine.ysl2	Mon Apr 01 20:58:40 2019 +0200
    25.3 @@ -3,7 +3,7 @@
    25.4  
    25.5  // generate state machine code
    25.6  
    25.7 -// Copyleft (c) 2016 - 2018, p≡p foundation
    25.8 +// Copyleft (c) 2016 - 2019, p≡p foundation
    25.9  
   25.10  // Written by Volker Birk
   25.11  
   25.12 @@ -55,7 +55,7 @@
   25.13  
   25.14          #define «yml:ucase(@name)»_TIMEOUT_EVENT new_«@name»_event(«@name»_PR_NOTHING, 0, NULL);
   25.15  
   25.16 -
   25.17 +    
   25.18          // free_«@name»_event() - free memory occupied by event
   25.19          //
   25.20          //  parameters:
   25.21 @@ -198,7 +198,8 @@
   25.22                      PEP_rating rating,
   25.23                      const char *data,
   25.24                      size_t size,
   25.25 -                    const char *fpr
   25.26 +                    const pEp_identity *from,
   25.27 +                    const char *signature_fpr
   25.28                  );
   25.29  
   25.30              #ifdef __cplusplus
   25.31 @@ -302,8 +303,7 @@
   25.32                  return PEP_STATUS_OK;
   25.33  
   25.34              the_end:
   25.35 -                free_«@name»_event(ev);
   25.36 -                free_«@name»_message(msg);
   25.37 +                free_«@name»_event(ev); // msg gets freed here
   25.38                  return status;
   25.39              }
   25.40  
   25.41 @@ -312,7 +312,8 @@
   25.42                      PEP_rating rating,
   25.43                      const char *data,
   25.44                      size_t size,
   25.45 -                    const char *fpr
   25.46 +                    const pEp_identity *from,
   25.47 +                    const char *signature_fpr
   25.48                  )
   25.49              {
   25.50                  assert(session && data && size);
   25.51 @@ -322,13 +323,32 @@
   25.52                  if (!session->inject_«yml:lcase(@name)»_event)
   25.53                     return PEP_«yml:ucase(@name)»_NO_INJECT_CALLBACK;
   25.54  
   25.55 +                PEP_STATUS status = PEP_STATUS_OK;
   25.56 +                «@name»_event_t *ev = NULL;
   25.57 +
   25.58 +                if (from) {
   25.59 +                    free_identity(session->«yml:lcase(@name)»_state.common.from);
   25.60 +                    session->«yml:lcase(@name)»_state.common.from = identity_dup(from);
   25.61 +                    if (!session->«yml:lcase(@name)»_state.common.from) {
   25.62 +                        status = PEP_OUT_OF_MEMORY;
   25.63 +                        goto the_end;
   25.64 +                    }
   25.65 +                }
   25.66 +
   25.67 +                if (signature_fpr) {
   25.68 +                    free(session->«yml:lcase(@name)»_state.common.signature_fpr);
   25.69 +                    session->«yml:lcase(@name)»_state.common.signature_fpr = strdup(signature_fpr);
   25.70 +                    if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
   25.71 +                        status = PEP_OUT_OF_MEMORY;
   25.72 +                        goto the_end;
   25.73 +                    }
   25.74 +                }
   25.75 +
   25.76                  «@name»_t *msg = NULL;
   25.77 -                PEP_STATUS status = decode_«@name»_message(data, size, &msg);
   25.78 +                status = decode_«@name»_message(data, size, &msg);
   25.79                  if (status)
   25.80                      return status;
   25.81  
   25.82 -                «@name»_event_t *ev = NULL;
   25.83 -
   25.84                  «@name»_PR fsm = msg->present;
   25.85                  int event = 0;
   25.86  
   25.87 @@ -339,17 +359,6 @@
   25.88                          goto the_end;
   25.89                  }
   25.90  
   25.91 -                if (fpr) {
   25.92 -                    if (session->«yml:lcase(@name)»_state.common.from->fpr)
   25.93 -                        free(session->«yml:lcase(@name)»_state.common.from->fpr);
   25.94 -                    session->«yml:lcase(@name)»_state.common.from->fpr = strdup(fpr);
   25.95 -                    assert(session->«yml:lcase(@name)»_state.common.from->fpr);
   25.96 -                    if (!session->«yml:lcase(@name)»_state.common.from->fpr) {
   25.97 -                        status = PEP_OUT_OF_MEMORY;
   25.98 -                        goto the_end;
   25.99 -                    }
  25.100 -                }
  25.101 -
  25.102                  ev = new_«@name»_event(fsm, event, msg);
  25.103                  if (!ev) {
  25.104                      status = PEP_OUT_OF_MEMORY;
  25.105 @@ -366,8 +375,7 @@
  25.106                  return PEP_STATUS_OK;
  25.107  
  25.108              the_end:
  25.109 -                free_«@name»_event(ev);
  25.110 -                free_«@name»_message(msg);
  25.111 +                free_«@name»_event(ev); // msg gets freed here
  25.112                  return status;
  25.113              }
  25.114  
  25.115 @@ -451,6 +459,7 @@
  25.116                                  goto the_end;
  25.117                              }
  25.118                          }
  25.119 +                        break;
  25.120  
  25.121                      default:
  25.122                          status = PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE;
  25.123 @@ -478,6 +487,7 @@
  25.124                                      _data,
  25.125                                      size,
  25.126                                      li->ident->fpr,
  25.127 +                                    NULL,
  25.128                                      &_m
  25.129                                  );
  25.130                              if (status) {
  25.131 @@ -488,6 +498,29 @@
  25.132                              m = _m;
  25.133                              break;
  25.134  
  25.135 +                    `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.136 +                            status = base_prepare_message(
  25.137 +                                    session,
  25.138 +                                    li->ident,
  25.139 +                                    li->ident,
  25.140 +                                    _data,
  25.141 +                                    size,
  25.142 +                                    NULL,
  25.143 +                                    &session->«yml:lcase(@name)»_state.common.own_keys,
  25.144 +                                    &_m
  25.145 +                                );
  25.146 +                            if (status) {
  25.147 +                                free(_data);
  25.148 +                                goto the_end;
  25.149 +                            }
  25.150 +                            status = encrypt_message(session, _m, NULL, &m, PEP_enc_PEP, 0);
  25.151 +                            if (status) {
  25.152 +                                status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
  25.153 +                                goto the_end;
  25.154 +                            }
  25.155 +                            free_message(_m);
  25.156 +                            break;
  25.157 +
  25.158                          default:
  25.159                              status = base_prepare_message(
  25.160                                      session,
  25.161 @@ -496,6 +529,7 @@
  25.162                                      _data,
  25.163                                      size,
  25.164                                      NULL,
  25.165 +                                    NULL,
  25.166                                      &_m
  25.167                                  );
  25.168                              if (status) {
  25.169 @@ -559,7 +593,7 @@
  25.170                  status = «@name»_driver(session, fsm, event);
  25.171  
  25.172              the_end:
  25.173 -                free_«@name»_event(ev);
  25.174 +                //free_«@name»_event(ev); // FIXME: We don't own this pointer. Are we sure it gets freed externally?
  25.175                  return status;
  25.176              }
  25.177  
  25.178 @@ -624,43 +658,54 @@
  25.179      {
  25.180          ||
  25.181          case «../@name»_PR_«yml:lcase(@name)»:
  25.182 -            event = msg->choice.«yml:lcase(@name)».payload.present;
  25.183 -            switch (event) {
  25.184 +            switch (msg->choice.«yml:lcase(@name)».payload.present) {
  25.185          ||
  25.186          if "message[@security='unencrypted']" {
  25.187 -            |         // these messages require a detached signature
  25.188 -            for "message[@security='unencrypted']"
  25.189 -                |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.190 +            |>> // these messages require a detached signature
  25.191 +            for "message[@security='unencrypted']" {
  25.192              ||
  25.193 -                        if (!fpr) {
  25.194 +                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.195 +                        if (!signature_fpr) {
  25.196                              status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.197                              goto the_end;
  25.198                          }
  25.199 +                        event = «@name»;
  25.200                          break;
  25.201  
  25.202              ||
  25.203 +            }
  25.204          }
  25.205 -        if "message[@security='untrusted']"
  25.206 +        if "message[@security='untrusted']" {
  25.207 +            |>> // these messages must arrive encrypted
  25.208 +            for "message[@security='untrusted']" {
  25.209 +            ||
  25.210 +                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.211 +                        if (rating < PEP_rating_reliable) {
  25.212 +                            status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.213 +                            goto the_end;
  25.214 +                        }
  25.215 +                        event = «@name»;
  25.216 +                        break;
  25.217 +
  25.218 +            ||
  25.219 +            }
  25.220 +        }
  25.221 +        if "message[@security='trusted']" {
  25.222 +            |>> // these messages must come through a trusted channel
  25.223 +            for "message[@security='trusted']" {
  25.224 +            ||
  25.225 +                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.226 +                        if (rating < PEP_rating_trusted) {
  25.227 +                            status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.228 +                            goto the_end;
  25.229 +                        }
  25.230 +                        event = «@name»;
  25.231 +                        break;
  25.232 +
  25.233 +            ||
  25.234 +            }
  25.235 +        }
  25.236          ||
  25.237 -                // these messages must arrive encrypted
  25.238 -        `` for "message[@security='untrusted']" |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
  25.239 -                    if (fpr || rating < PEP_rating_reliable) {
  25.240 -                        status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.241 -                        goto the_end;
  25.242 -                    }
  25.243 -                    break;
  25.244 -
  25.245 -        ||
  25.246 -        if "message[@security='trusted']"
  25.247 -        ||
  25.248 -                // these messages must come through a trusted channel
  25.249 -        `` for "message[@security='trusted']" |>> case «ancestor::fsm/@name»__payload_PR_«yml:mixedCase(@name)»:
  25.250 -                    if (fpr || rating < PEP_rating_trusted) {
  25.251 -                        status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.252 -                        goto the_end;
  25.253 -                    }
  25.254 -                    break;
  25.255 -
  25.256                  default:
  25.257                      status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
  25.258                      goto the_end;
  25.259 @@ -744,15 +789,16 @@
  25.260              «@name»_event_None = None,
  25.261              «@name»_event_Init = Init,
  25.262          ||
  25.263 -        for "func:distinctName(state/event[not(not(../../message/@name=@name))])" {
  25.264 +        for "message" {
  25.265              const "name", "@name";
  25.266              |> «$name» = «/protocol/fsm/message[@name=$name]/@id»,
  25.267          }
  25.268 -        for "func:distinctName(state/event[not(not(../../external/@name=@name))])" {
  25.269 -            const "name", "@name";
  25.270 -            |> «$name» = «/protocol/fsm/external[@name=$name]/@id»,
  25.271 +        |> «@name»_event_Extra = Extra,
  25.272 +        for "external" {
  25.273 +            if "@id < 128"
  25.274 +                error > external «@name» must have ID >= 128 but it's «@id»
  25.275 +            |> «@name» = «@id»,
  25.276          }
  25.277 -        |> «@name»_event_Extra = Extra,
  25.278          for "func:distinctName(state/event[not(../../message/@name=@name or ../../external/@name=@name)])" {
  25.279              if "@name!='Init'"
  25.280                  |> «@name»`if "position()!=last()" > , `
  25.281 @@ -856,13 +902,6 @@
  25.282  
  25.283          #define «@name»_ERR_LOG_INT(t, n) _«@name»_ERR_LOG_int(session, (t), (n), false)
  25.284          #define «@name»_ERR_LOG_HEX(t, n) _«@name»_ERR_LOG_int(session, (t), (n), true)
  25.285 -
  25.286 -        #ifndef SERVICE_LOG
  25.287 -        // SERVICE LOG is meant to check session->service_log in runtime config;
  25.288 -        // for older engines log more than needed
  25.289 -        #define SERVICE_LOG(session, t, n, d) log_event((session), (t), (n), (d), "service")
  25.290 -        #endif 
  25.291 -
  25.292          #define «@name»_SERVICE_LOG(t, d) SERVICE_LOG(session, (t), "«@name»", (d))
  25.293  
  25.294          «@name»_state fsm_«@name»(
  25.295 @@ -875,10 +914,10 @@
  25.296              if (!session)
  25.297                  return invalid_state;
  25.298  
  25.299 +            if (state == None)
  25.300 +                state = «@name»_state_Init;
  25.301 +
  25.302              switch (state) {
  25.303 -                case None:
  25.304 -                    return «@name»_state_Init;
  25.305 -                
  25.306                  `` apply "state", 2, mode=fsm
  25.307                  default:
  25.308                      «@name»_ERR_LOG_INT("invalid state", state);
  25.309 @@ -909,7 +948,7 @@
  25.310          if "not(event[@name='Init'])"
  25.311          ||
  25.312                  case Init:
  25.313 -                    // nothing to do
  25.314 +                    «../@name»_SERVICE_LOG("received Init but nothing to do", "Init");
  25.315                      break;
  25.316  
  25.317          ||
  25.318 @@ -918,7 +957,7 @@
  25.319                  default:
  25.320                      // ignore events not handled here
  25.321                      «../@name»_SERVICE_LOG("ignoring event", KeySync_event_name(event));
  25.322 -                    break;
  25.323 +                    return invalid_event;
  25.324              }
  25.325              break;
  25.326  
  25.327 @@ -1013,4 +1052,3 @@
  25.328          | }
  25.329      }
  25.330  }
  25.331 -
    26.1 --- a/sync/sync.fsm	Thu Feb 07 16:02:11 2019 +0100
    26.2 +++ b/sync/sync.fsm	Mon Apr 01 20:58:40 2019 +0200
    26.3 @@ -1,7 +1,7 @@
    26.4  // This file is under BSD License 2.0
    26.5  
    26.6  // Sync protocol for p≡p
    26.7 -// Copyright (c) 2016 - 2018, p≡p foundation
    26.8 +// Copyright (c) 2016 - 2019, p≡p foundation
    26.9  
   26.10  // Written by Volker Birk
   26.11  
   26.12 @@ -51,13 +51,12 @@
   26.13                      send HandshakeAnswer;
   26.14                      if partnerIsGrouped
   26.15                          go HandshakingWithGroup;
   26.16 -
   26.17 -                    go HandshakingNew();
   26.18 +                    go HandshakingNew;
   26.19                  }
   26.20              }
   26.21  
   26.22              on HandshakeAnswer
   26.23 -                go HandshakingNew();
   26.24 +                go HandshakingNew;
   26.25          }
   26.26  
   26.27          // handshaking without existing Device group
   26.28 @@ -126,16 +125,16 @@
   26.29          }
   26.30  
   26.31          state NewGroup {
   26.32 -            on Init
   26.33 +            on Init {
   26.34 +                do prepareOwnKeys;
   26.35                  send GroupKeysAndClose; // we're not grouped yet, this is our own keys
   26.36 +            }
   26.37  
   26.38              on GroupKeysAndClose {
   26.39 -                do saveGroupKeys;
   26.40 -                if keyElectionWon {
   26.41 +                if keyElectionWon
   26.42                      do ownKeysAreGroupKeys;
   26.43 -                    go Grouped;
   26.44 -                }
   26.45 -                // do receivedKeysAreGroupKeys; -- implicit
   26.46 +                else
   26.47 +                    do receivedKeysAreGroupKeys;
   26.48                  go Grouped;
   26.49              }
   26.50          }
   26.51 @@ -297,9 +296,9 @@
   26.52                  do saveGroupKeys;
   26.53          }
   26.54   
   26.55 -        external Accept 30;
   26.56 -        external Reject 31;
   26.57 -        external Cancel 32;
   26.58 +        external Accept 129;
   26.59 +        external Reject 130;
   26.60 +        external Cancel 131;
   26.61  
   26.62          // beacons are always broadcasted
   26.63  
   26.64 @@ -312,13 +311,12 @@
   26.65              field TID challenge;
   26.66              auto Version version;
   26.67              field TID transaction;
   26.68 -            field Hash fpr;
   26.69              field bool is_group;
   26.70          }
   26.71  
   26.72 -        message HandshakeAnswer 4 {
   26.73 +        message HandshakeAnswer 4, security=untrusted {
   26.74 +            auto Version version;
   26.75              field TID transaction;
   26.76 -            field Hash fpr;
   26.77          }
   26.78  
   26.79          message Rollback 5, security=untrusted {
   26.80 @@ -333,13 +331,13 @@
   26.81              field TID transaction;
   26.82          }
   26.83  
   26.84 -        message GroupKeysAndClose 8 {
   26.85 +        message GroupKeysAndClose 8, security=attach_own_keys {
   26.86              field TID transaction;
   26.87 -            field IdentityList identities;
   26.88 +            field IdentityList ownIdentities;
   26.89          }
   26.90  
   26.91 -        message GroupKeys 9 {
   26.92 -            field IdentityList identities;
   26.93 +        message GroupKeys 9, security=attach_own_keys {
   26.94 +            field IdentityList ownIdentities;
   26.95          }
   26.96      }
   26.97  }
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/include/EnterLeaveDeviceGroupTests.h	Mon Apr 01 20:58:40 2019 +0200
    27.3 @@ -0,0 +1,28 @@
    27.4 +// This file is under GNU General Public License 3.0
    27.5 +// see LICENSE.txt
    27.6 +
    27.7 +#ifndef ENTER_LEAVE_DEVICE_GROUP_H
    27.8 +#define ENTER_LEAVE_DEVICE_GROUP_H
    27.9 +
   27.10 +#include <string>
   27.11 +#include "EngineTestIndividualSuite.h"
   27.12 +
   27.13 +using namespace std;
   27.14 +
   27.15 +class EnterLeaveDeviceGroupTests : public EngineTestIndividualSuite {
   27.16 +    public:
   27.17 +        EnterLeaveDeviceGroupTests(string test_suite, string test_home_dir);
   27.18 +    private:
   27.19 +        void check_enter_device_group_no_own();    
   27.20 +        void check_enter_device_group_one_own_empty();    
   27.21 +        void check_enter_device_group_one_own_one();    
   27.22 +        void check_enter_device_group_one_own_many();    
   27.23 +        void check_enter_device_group_one_own_single_not_me();    
   27.24 +        void check_enter_device_group_one_own_single_many_w_not_me();    
   27.25 +        void check_enter_device_group_many_empty();    
   27.26 +        void check_enter_device_group_many_own_one();    
   27.27 +        void check_enter_device_group_many_own_many();    
   27.28 +        void check_enter_device_group_many_own_many_w_not_me();    
   27.29 +};
   27.30 +
   27.31 +#endif
    28.1 --- a/test/include/NewUpdateIdAndMyselfTests.h	Thu Feb 07 16:02:11 2019 +0100
    28.2 +++ b/test/include/NewUpdateIdAndMyselfTests.h	Mon Apr 01 20:58:40 2019 +0200
    28.3 @@ -12,8 +12,40 @@
    28.4  class NewUpdateIdAndMyselfTests : public EngineTestSessionSuite {
    28.5      public:
    28.6          NewUpdateIdAndMyselfTests(string test_suite, string test_home_dir);
    28.7 +	protected:
    28.8 +		char* uniqname;
    28.9 +		char* own_user_id;
   28.10 +		char* start_username;
   28.11 +		char* generated_fpr;
   28.12 +		char* default_own_id;
   28.13 +		char* alias_id;
   28.14 +        char* new_fpr;
   28.15 +        const char* alex_address;
   28.16 +        const char* alex_fpr;
   28.17 +        const char* alex_userid;
   28.18 +        const char* alex_username;
   28.19 +        const char* new_username;
   28.20 +    
   28.21 +        void setup();
   28.22 +        void tear_down();
   28.23      private:
   28.24 -        void check_new_update_id_and_myself();
   28.25 +        void myself_no_record_no_input_fpr();
   28.26 +        void myself_no_input_fpr_w_record();
   28.27 +        void myself_no_input_fpr_diff_user_id_w_record();
   28.28 +        void myself_replace_fpr();
   28.29 +        void myself_replace_fpr_revoke_key();
   28.30 +        void update_identity_w_matching_address_user_id_username();
   28.31 +        void update_identity_w_matching_address_user_id_new_username();
   28.32 +        void update_identity_w_matching_address_user_id_only();
   28.33 +        void update_identity_use_address_username_only();
   28.34 +        void update_identity_use_address_only();
   28.35 +        void update_identity_use_address_only_on_own_ident();
   28.36 +        void update_identity_non_existent_user_id_address();
   28.37 +        void update_identity_address_username_userid_no_record();
   28.38 +        void update_identity_address_username_no_record();
   28.39 +        void update_identity_address_only_multiple_records();
   28.40 +        void key_elect_expired_key();
   28.41 +        void key_elect_only_revoked_mistrusted();
   28.42  };
   28.43  
   28.44  #endif
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/include/NoOwnIdentWritesOnDecryptTests.h	Mon Apr 01 20:58:40 2019 +0200
    29.3 @@ -0,0 +1,25 @@
    29.4 +// This file is under GNU General Public License 3.0
    29.5 +// see LICENSE.txt
    29.6 +
    29.7 +#ifndef NO_OWN_IDENT_WRITES_ON_DECRYPT_H
    29.8 +#define NO_OWN_IDENT_WRITES_ON_DECRYPT_H
    29.9 +
   29.10 +#include <string>
   29.11 +#include "EngineTestIndividualSuite.h"
   29.12 +#include "pEpEngine.h"
   29.13 +#include "message.h"
   29.14 +
   29.15 +using namespace std;
   29.16 +
   29.17 +class NoOwnIdentWritesOnDecryptTests : public EngineTestIndividualSuite {
   29.18 +    public:
   29.19 +        NoOwnIdentWritesOnDecryptTests(string test_suite, string test_home_dir);
   29.20 +        ~NoOwnIdentWritesOnDecryptTests();
   29.21 +        message* _to_decrypt;
   29.22 +    private:
   29.23 +        void check_no_own_ident_writes_on_decrypt();        
   29.24 +        void check_address_only_no_overwrite();
   29.25 +        void check_full_info_no_overwrite();
   29.26 +};
   29.27 +
   29.28 +#endif
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/include/OwnIdentitiesRetrieveTests.h	Mon Apr 01 20:58:40 2019 +0200
    30.3 @@ -0,0 +1,19 @@
    30.4 +// This file is under GNU General Public License 3.0
    30.5 +// see LICENSE.txt
    30.6 +
    30.7 +#ifndef OWN_IDENTITIES_RETRIEVE_H
    30.8 +#define OWN_IDENTITIES_RETRIEVE_H
    30.9 +
   30.10 +#include <string>
   30.11 +#include "EngineTestIndividualSuite.h"
   30.12 +
   30.13 +using namespace std;
   30.14 +
   30.15 +class OwnIdentitiesRetrieveTests : public EngineTestIndividualSuite {
   30.16 +    public:
   30.17 +        OwnIdentitiesRetrieveTests(string test_suite, string test_home_dir);
   30.18 +    private:
   30.19 +        void check_own_identities_retrieve();
   30.20 +};
   30.21 +
   30.22 +#endif
    31.1 --- a/test/include/StringlistTests.h	Thu Feb 07 16:02:11 2019 +0100
    31.2 +++ b/test/include/StringlistTests.h	Mon Apr 01 20:58:40 2019 +0200
    31.3 @@ -14,6 +14,7 @@
    31.4          StringlistTests(string suitename, string test_home_dir);
    31.5      private:
    31.6          void check_stringlists();
    31.7 +        void check_dedup_stringlist();
    31.8  };
    31.9  
   31.10  #endif
    32.1 --- a/test/include/locked_queue.hh	Thu Feb 07 16:02:11 2019 +0100
    32.2 +++ b/test/include/locked_queue.hh	Mon Apr 01 20:58:40 2019 +0200
    32.3 @@ -58,4 +58,4 @@
    32.4              return _q.empty();
    32.5          }
    32.6      };
    32.7 -};
    32.8 +}
    33.1 --- a/test/include/test_util.h	Thu Feb 07 16:02:11 2019 +0100
    33.2 +++ b/test/include/test_util.h	Mon Apr 01 20:58:40 2019 +0200
    33.3 @@ -44,6 +44,8 @@
    33.4  // Returns the string value of the input status enum value. 
    33.5  const char* tl_status_string(PEP_STATUS status);
    33.6  
    33.7 +std::string tl_ident_flags_String(identity_flags_t fl);
    33.8 +
    33.9  // Grabs a new uuid for your randomish string needs.
   33.10  char* get_new_uuid();
   33.11  
    34.1 --- a/test/src/EngineTestSuite.cc	Thu Feb 07 16:02:11 2019 +0100
    34.2 +++ b/test/src/EngineTestSuite.cc	Mon Apr 01 20:58:40 2019 +0200
    34.3 @@ -103,10 +103,12 @@
    34.4  
    34.5  // FIXME
    34.6  #ifndef USE_NETPGP
    34.7 +#ifndef USE_SEQUOIA
    34.8      success = system("gpgconf --kill all");
    34.9      if (success != 0)
   34.10          throw std::runtime_error("SETUP: Error when executing 'gpgconf --kill all'.");    
   34.11  #endif
   34.12 +#endif
   34.13  
   34.14      if (stat(test_home.c_str(), &dirchk) == 0) {
   34.15          if (!S_ISDIR(dirchk.st_mode))
   34.16 @@ -217,12 +219,14 @@
   34.17      
   34.18  //    cout << "calling init()\n";
   34.19      PEP_STATUS status = init(&session, cached_messageToSend, cached_inject_sync_event);
   34.20 -#ifndef USE_NETPGP            
   34.21 +#ifndef USE_NETPGP
   34.22 +#ifndef USE_SEQUOIA
   34.23      success = system("gpgconf --create-socketdir");
   34.24      if (success != 0)
   34.25          throw std::runtime_error("RESTORE: Error when executing 'gpgconf --create-socketdir'.");        
   34.26      system("gpg-connect-agent /bye");   // Just in case - otherwise, we die on MacOS sometimes. Is this enough??
   34.27  #endif
   34.28 +#endif
   34.29  
   34.30      assert(status == PEP_STATUS_OK);
   34.31      assert(session);
   34.32 @@ -236,7 +240,8 @@
   34.33          
   34.34      int success = 0;    
   34.35  
   34.36 -#ifndef USE_NETPGP        
   34.37 +#ifndef USE_NETPGP 
   34.38 +#ifndef USE_SEQUOIA
   34.39      success = system("gpgconf --kill all");
   34.40      if (success != 0)
   34.41          throw std::runtime_error("RESTORE: Error when executing 'gpgconf --kill all'.");
   34.42 @@ -244,6 +249,7 @@
   34.43      if (success != 0)
   34.44          throw std::runtime_error("RESTORE: Error when executing 'gpgconf --remove-socketdir'.");    
   34.45  #endif
   34.46 +#endif
   34.47  
   34.48      success = setenv("GNUPGHOME", prev_pgp_home.c_str(), 1);
   34.49      if (success != 0)
    35.1 --- a/test/src/SuiteMaker.cc	Thu Feb 07 16:02:11 2019 +0100
    35.2 +++ b/test/src/SuiteMaker.cc	Mon Apr 01 20:58:40 2019 +0200
    35.3 @@ -13,11 +13,13 @@
    35.4  
    35.5  // Begin where we generate stuff
    35.6  #include "MimeTests.h"
    35.7 +#include "OwnIdentitiesRetrieveTests.h"
    35.8  #include "ExpiredSubkeyTests.h"
    35.9  #include "UserIdCollisionTests.h"
   35.10  #include "Engine463Tests.h"
   35.11  #include "BloblistTests.h"
   35.12  #include "NewUpdateIdAndMyselfTests.h"
   35.13 +#include "NoOwnIdentWritesOnDecryptTests.h"
   35.14  #include "I18nTests.h"
   35.15  #include "IdentityListTests.h"
   35.16  #include "PgpBinaryTests.h"
   35.17 @@ -30,12 +32,12 @@
   35.18  #include "EncryptMissingPrivateKeyTests.h"
   35.19  #include "CaseAndDotAddressTests.h"
   35.20  #include "UserIDAliasTests.h"
   35.21 +#include "EnterLeaveDeviceGroupTests.h"
   35.22  #include "SignOnlyTests.h"
   35.23  #include "BCCTests.h"
   35.24  #include "Engine358Tests.h"
   35.25  #include "BlacklistAcceptNewKeyTests.h"
   35.26  #include "DecryptAttachPrivateKeyUntrustedTests.h"
   35.27 -#include "ReturnMistrustFprTests.h"
   35.28  #include "BlacklistTests.h"
   35.29  #include "RevokeRegenAttachTests.h"
   35.30  #include "PepSubjectReceivedTests.h"
   35.31 @@ -65,11 +67,13 @@
   35.32  
   35.33  const char* SuiteMaker::all_suites[] = {
   35.34      "MimeTests",
   35.35 +    "OwnIdentitiesRetrieveTests",
   35.36      "ExpiredSubkeyTests",
   35.37      "UserIdCollisionTests",
   35.38      "Engine463Tests",
   35.39      "BloblistTests",
   35.40      "NewUpdateIdAndMyselfTests",
   35.41 +    "NoOwnIdentWritesOnDecryptTests",
   35.42      "I18nTests",
   35.43      "IdentityListTests",
   35.44      "PgpBinaryTests",
   35.45 @@ -82,12 +86,12 @@
   35.46      "EncryptMissingPrivateKeyTests",
   35.47      "CaseAndDotAddressTests",
   35.48      "UserIDAliasTests",
   35.49 +    "EnterLeaveDeviceGroupTests",
   35.50      "SignOnlyTests",
   35.51      "BCCTests",
   35.52      "Engine358Tests",
   35.53      "BlacklistAcceptNewKeyTests",
   35.54      "DecryptAttachPrivateKeyUntrustedTests",
   35.55 -    "ReturnMistrustFprTests",
   35.56      "BlacklistTests",
   35.57      "RevokeRegenAttachTests",
   35.58      "PepSubjectReceivedTests",
   35.59 @@ -116,11 +120,13 @@
   35.60  };
   35.61  
   35.62  // This file is generated, so magic constants are ok.
   35.63 -int SuiteMaker::num_suites = 49;
   35.64 +int SuiteMaker::num_suites = 51;
   35.65  
   35.66  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   35.67      if (strcmp(test_class_name, "MimeTests") == 0)
   35.68          *test_suite = new MimeTests(test_class_name, test_home);
   35.69 +    else if (strcmp(test_class_name, "OwnIdentitiesRetrieveTests") == 0)
   35.70 +        *test_suite = new OwnIdentitiesRetrieveTests(test_class_name, test_home);
   35.71      else if (strcmp(test_class_name, "ExpiredSubkeyTests") == 0)
   35.72          *test_suite = new ExpiredSubkeyTests(test_class_name, test_home);
   35.73      else if (strcmp(test_class_name, "UserIdCollisionTests") == 0)
   35.74 @@ -131,6 +137,8 @@
   35.75          *test_suite = new BloblistTests(test_class_name, test_home);
   35.76      else if (strcmp(test_class_name, "NewUpdateIdAndMyselfTests") == 0)
   35.77          *test_suite = new NewUpdateIdAndMyselfTests(test_class_name, test_home);
   35.78 +    else if (strcmp(test_class_name, "NoOwnIdentWritesOnDecryptTests") == 0)
   35.79 +        *test_suite = new NoOwnIdentWritesOnDecryptTests(test_class_name, test_home);
   35.80      else if (strcmp(test_class_name, "I18nTests") == 0)
   35.81          *test_suite = new I18nTests(test_class_name, test_home);
   35.82      else if (strcmp(test_class_name, "IdentityListTests") == 0)
   35.83 @@ -155,6 +163,8 @@
   35.84          *test_suite = new CaseAndDotAddressTests(test_class_name, test_home);
   35.85      else if (strcmp(test_class_name, "UserIDAliasTests") == 0)
   35.86          *test_suite = new UserIDAliasTests(test_class_name, test_home);
   35.87 +    else if (strcmp(test_class_name, "EnterLeaveDeviceGroupTests") == 0)
   35.88 +        *test_suite = new EnterLeaveDeviceGroupTests(test_class_name, test_home);
   35.89      else if (strcmp(test_class_name, "SignOnlyTests") == 0)
   35.90          *test_suite = new SignOnlyTests(test_class_name, test_home);
   35.91      else if (strcmp(test_class_name, "BCCTests") == 0)
   35.92 @@ -165,8 +175,6 @@
   35.93          *test_suite = new BlacklistAcceptNewKeyTests(test_class_name, test_home);
   35.94      else if (strcmp(test_class_name, "DecryptAttachPrivateKeyUntrustedTests") == 0)
   35.95          *test_suite = new DecryptAttachPrivateKeyUntrustedTests(test_class_name, test_home);
   35.96 -    else if (strcmp(test_class_name, "ReturnMistrustFprTests") == 0)
   35.97 -        *test_suite = new ReturnMistrustFprTests(test_class_name, test_home);
   35.98      else if (strcmp(test_class_name, "BlacklistTests") == 0)
   35.99          *test_suite = new BlacklistTests(test_class_name, test_home);
  35.100      else if (strcmp(test_class_name, "RevokeRegenAttachTests") == 0)
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/test/src/engine_tests/EnterLeaveDeviceGroupTests.cc	Mon Apr 01 20:58:40 2019 +0200
    36.3 @@ -0,0 +1,136 @@
    36.4 +// This file is under GNU General Public License 3.0
    36.5 +// see LICENSE.txt
    36.6 +
    36.7 +#include <stdlib.h>
    36.8 +#include <string>
    36.9 +#include <cstring>
   36.10 +
   36.11 +#include "pEpEngine.h"
   36.12 +
   36.13 +#include "test_util.h"
   36.14 +#include "sync_api.h"
   36.15 +#include <cpptest.h>
   36.16 +#include "EngineTestIndividualSuite.h"
   36.17 +#include "EnterLeaveDeviceGroupTests.h"
   36.18 +
   36.19 +using namespace std;
   36.20 +
   36.21 +EnterLeaveDeviceGroupTests::EnterLeaveDeviceGroupTests(string suitename, string test_home_dir) :
   36.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   36.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_no_own"),
   36.24 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_no_own)));
   36.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_empty"),
   36.26 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_empty)));
   36.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_one"),
   36.28 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_one)));
   36.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_many"),
   36.30 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_many)));
   36.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_not_me"),
   36.32 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_not_me)));
   36.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_many_w_not_me"),
   36.34 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_many_w_not_me)));
   36.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_many_empty"),
   36.36 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_many_empty)));
   36.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_one"),
   36.38 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_one)));
   36.39 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many"),
   36.40 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many)));
   36.41 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many_w_not_me"),
   36.42 +                                                                      static_cast<Func>(&EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many_w_not_me)));
   36.43 +}
   36.44 +
   36.45 +void EnterLeaveDeviceGroupTests::check_enter_device_group_no_own() {    
   36.46 +    pEp_identity* alice_id = NULL;
   36.47 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));
   36.48 +    PEP_STATUS status = set_up_ident_from_scratch(session,
   36.49 +                                "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc",
   36.50 +                                "pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", 
   36.51 +                                "ALICE", "Alice in Wonderland", &alice_id, false
   36.52 +                        );
   36.53 +                        
   36.54 +    TEST_ASSERT(status == PEP_STATUS_OK);
   36.55 +    status = enter_device_group(session, NULL);
   36.56 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   36.57 +    
   36.58 +    status = update_identity(session, alice_id);
   36.59 +    TEST_ASSERT(!(alice_id->flags & PEP_idf_devicegroup));
   36.60 +
   36.61 +    TEST_ASSERT(true);
   36.62 +}
   36.63 +
   36.64 +void EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_empty() {    
   36.65 +    pEp_identity* alice_id = NULL;
   36.66 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));    
   36.67 +    PEP_STATUS status = set_up_ident_from_scratch(session,
   36.68 +                                "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc",
   36.69 +                                "pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", 
   36.70 +                                "ALICE", "Alice in Wonderland", &alice_id, true
   36.71 +                        );    
   36.72 +
   36.73 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   36.74 +    status = myself(session, alice_id);
   36.75 +
   36.76 +    TEST_ASSERT(alice_id->me);
   36.77 +    TEST_ASSERT(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
   36.78 +    status = enter_device_group(session, NULL);
   36.79 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   36.80 +    
   36.81 +    status = myself(session, alice_id);
   36.82 +    TEST_ASSERT(status == PEP_STATUS_OK);    
   36.83 +    TEST_ASSERT_MSG(alice_id->flags & PEP_idf_devicegroup, tl_ident_flags_String(alice_id->flags).c_str());
   36.84 +                        
   36.85 +    TEST_ASSERT(true);
   36.86 +}
   36.87 +
   36.88 +void EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_one() {    
   36.89 +    pEp_identity* alice_id = NULL;
   36.90 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));    
   36.91 +    PEP_STATUS status = set_up_ident_from_scratch(session,
   36.92 +                                "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc",
   36.93 +                                "pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", 
   36.94 +                                "ALICE", "Alice in Wonderland", &alice_id, true
   36.95 +                        );    
   36.96 +
   36.97 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   36.98 +    status = myself(session, alice_id);
   36.99 +
  36.100 +    TEST_ASSERT(alice_id->me);
  36.101 +    TEST_ASSERT(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
  36.102 +    identity_list* ids_to_group = new_identity_list(alice_id);
  36.103 +    status = enter_device_group(session, ids_to_group);
  36.104 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  36.105 +    
  36.106 +    status = myself(session, alice_id);
  36.107 +    TEST_ASSERT(status == PEP_STATUS_OK);    
  36.108 +    TEST_ASSERT_MSG(alice_id->flags & PEP_idf_devicegroup, tl_ident_flags_String(alice_id->flags).c_str());
  36.109 +                        
  36.110 +    TEST_ASSERT(true);
  36.111 +}
  36.112 +
  36.113 +void EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_many() {    
  36.114 +    TEST_ASSERT(true);
  36.115 +}
  36.116 +
  36.117 +void EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_not_me() {    
  36.118 +    TEST_ASSERT(true);
  36.119 +}
  36.120 +
  36.121 +void EnterLeaveDeviceGroupTests::check_enter_device_group_one_own_single_many_w_not_me() {    
  36.122 +    TEST_ASSERT(true);
  36.123 +}
  36.124 +
  36.125 +void EnterLeaveDeviceGroupTests::check_enter_device_group_many_empty() {    
  36.126 +    TEST_ASSERT(true);
  36.127 +}
  36.128 +
  36.129 +void EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_one() {    
  36.130 +    TEST_ASSERT(true);
  36.131 +}
  36.132 +
  36.133 +void EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many() {    
  36.134 +    TEST_ASSERT(true);
  36.135 +}
  36.136 +
  36.137 +void EnterLeaveDeviceGroupTests::check_enter_device_group_many_own_many_w_not_me() {    
  36.138 +    TEST_ASSERT(true);
  36.139 +}
    37.1 --- a/test/src/engine_tests/MessageApiTests.cc	Thu Feb 07 16:02:11 2019 +0100
    37.2 +++ b/test/src/engine_tests/MessageApiTests.cc	Mon Apr 01 20:58:40 2019 +0200
    37.3 @@ -142,7 +142,7 @@
    37.4      PEP_decrypt_flags_t flags2;
    37.5      flags2 = 0;
    37.6      PEP_STATUS status6 = decrypt_message(session, msg5, &msg6, &keylist5, &rating2, &flags2);
    37.7 -    TEST_ASSERT_MSG((status6 == PEP_DECRYPT_NO_KEY), "status6 == PEP_DECRYPT_NO_KEY");
    37.8 +    TEST_ASSERT_MSG((status6 == PEP_DECRYPT_NO_KEY), tl_status_string(status6));
    37.9      TEST_ASSERT_MSG((msg6 == NULL), "msg6 == NULL");
   37.10      TEST_ASSERT_MSG((keylist5 == NULL), "keylist5 == NULL");
   37.11      TEST_ASSERT_MSG((rating2 == PEP_rating_have_no_key), "rating2 == PEP_rating_have_no_key");
    38.1 --- a/test/src/engine_tests/NewUpdateIdAndMyselfTests.cc	Thu Feb 07 16:02:11 2019 +0100
    38.2 +++ b/test/src/engine_tests/NewUpdateIdAndMyselfTests.cc	Mon Apr 01 20:58:40 2019 +0200
    38.3 @@ -21,55 +21,98 @@
    38.4  
    38.5  NewUpdateIdAndMyselfTests::NewUpdateIdAndMyselfTests(string suitename, string test_home_dir) :
    38.6      EngineTestSessionSuite::EngineTestSessionSuite(suitename, test_home_dir) {
    38.7 -    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::check_new_update_id_and_myself"),
    38.8 -                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::check_new_update_id_and_myself)));
    38.9 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::myself_no_record_no_input_fpr"),
   38.10 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::myself_no_record_no_input_fpr)));
   38.11 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::myself_no_input_fpr_w_record"),
   38.12 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::myself_no_input_fpr_w_record)));
   38.13 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::myself_no_input_fpr_diff_user_id_w_record"),
   38.14 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::myself_no_input_fpr_diff_user_id_w_record)));
   38.15 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::myself_replace_fpr"),
   38.16 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::myself_replace_fpr)));
   38.17 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::myself_replace_fpr_revoke_key"),
   38.18 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::myself_replace_fpr_revoke_key)));
   38.19 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_username"),
   38.20 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_username)));
   38.21 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_new_username"),
   38.22 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_new_username)));
   38.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_only"),
   38.24 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_only)));
   38.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_use_address_username_only"),
   38.26 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_use_address_username_only)));
   38.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_use_address_only"),
   38.28 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_use_address_only)));
   38.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_use_address_only_on_own_ident"),
   38.30 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_use_address_only_on_own_ident)));
   38.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_non_existent_user_id_address"),
   38.32 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_non_existent_user_id_address)));
   38.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_address_username_userid_no_record"),
   38.34 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_address_username_userid_no_record)));
   38.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_address_username_no_record"),
   38.36 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_address_username_no_record)));
   38.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::update_identity_address_only_multiple_records"),
   38.38 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::update_identity_address_only_multiple_records)));
   38.39 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::key_elect_expired_key"),
   38.40 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::key_elect_expired_key)));
   38.41 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NewUpdateIdAndMyselfTests::key_elect_only_revoked_mistrusted"),
   38.42 +                                                                      static_cast<Func>(&NewUpdateIdAndMyselfTests::key_elect_only_revoked_mistrusted)));
   38.43  }
   38.44  
   38.45 -void NewUpdateIdAndMyselfTests::check_new_update_id_and_myself() {
   38.46 -    
   38.47 +void NewUpdateIdAndMyselfTests::setup() {
   38.48 +    EngineTestSessionSuite::setup();
   38.49 +    if (on_test_number == 1) {
   38.50 +        uniqname = strdup("AAAAtestuser@testdomain.org");
   38.51 +        srandom(time(NULL));
   38.52 +        for(int i=0; i < 4;i++)
   38.53 +        uniqname[i] += random() & 0xf;
   38.54 +        
   38.55 +        own_user_id = get_new_uuid();
   38.56 +        start_username = strdup("Unser Testkandidat");
   38.57 +        generated_fpr = NULL;
   38.58 +        default_own_id = NULL;
   38.59 +        alias_id = NULL;
   38.60 +        new_fpr = NULL;
   38.61 +        alex_address = "pep.test.alexander@peptest.ch";
   38.62 +        alex_fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
   38.63 +        alex_userid = "Alex";
   38.64 +        alex_username = "SuperDuperAlex";
   38.65 +    }    
   38.66 +}
   38.67 +
   38.68 +void NewUpdateIdAndMyselfTests::tear_down() {
   38.69 +    if (on_test_number == number_of_tests) {
   38.70 +        free(uniqname);
   38.71 +        free(own_user_id);
   38.72 +        free(start_username);
   38.73 +        free(generated_fpr);
   38.74 +        free(default_own_id);
   38.75 +        free(alias_id);
   38.76 +        free(new_fpr);
   38.77 +    }
   38.78 +    EngineTestSessionSuite::tear_down();
   38.79 +}
   38.80 +
   38.81 +void NewUpdateIdAndMyselfTests::myself_no_record_no_input_fpr() {
   38.82      PEP_STATUS status = PEP_STATUS_OK;
   38.83      
   38.84 -    cout << "***********************************************************************" << endl;
   38.85 -    cout << "* Section I. myself()" << endl;
   38.86 -    cout << "***********************************************************************" << endl << endl;
   38.87 -
   38.88 -    // Create id with no key
   38.89 -    cout << "Creating new own id with no key for : ";
   38.90 -    char *uniqname = strdup("AAAAtestuser@testdomain.org");
   38.91 -    srandom(time(NULL));
   38.92 -    for(int i=0; i < 4;i++)
   38.93 -        uniqname[i] += random() & 0xf;
   38.94 -    
   38.95 -    cout << uniqname << "\n";
   38.96 -    
   38.97 -    const char* own_user_id = get_new_uuid();
   38.98 -    const char* start_username = "Unser Testkandidat";
   38.99 -
  38.100      pEp_identity * new_me = new_identity(uniqname, NULL, own_user_id, start_username);
  38.101      
  38.102 -    cout << "***********************************************************************" << endl;
  38.103 -    cout << "* I: 1. myself() on id with no record in the DB and no input fpr" << endl;
  38.104 -    cout << "***********************************************************************" << endl << endl;
  38.105      status = myself(session, new_me);
  38.106 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.107 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.108      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.109      
  38.110 -    cout << "PASS: myself() generated fingerprint ";
  38.111 -    cout << new_me->fpr << endl << endl;
  38.112 -
  38.113 -    char* generated_fpr = strdup(new_me->fpr);
  38.114 +    generated_fpr = strdup(new_me->fpr);
  38.115      
  38.116      TEST_ASSERT_MSG((new_me->comm_type == PEP_ct_pEp), "new_me->comm_type == PEP_ct_pEp");
  38.117      
  38.118      free_identity(new_me);
  38.119 +}
  38.120  
  38.121 -    cout << "***********************************************************************" << endl;
  38.122 -    cout << "* I: 2. myself() on id with no input fpr and a record in the DB" << endl;
  38.123 -    cout << "***********************************************************************" << endl << endl;
  38.124 -
  38.125 -    new_me = new_identity(uniqname, NULL, own_user_id, NULL);
  38.126 +void NewUpdateIdAndMyselfTests::myself_no_input_fpr_w_record() {
  38.127 +    PEP_STATUS status = PEP_STATUS_OK;
  38.128 +    
  38.129 +    pEp_identity* new_me = new_identity(uniqname, NULL, own_user_id, NULL);
  38.130      status = myself(session, new_me);
  38.131 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.132 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.133      
  38.134      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.135      TEST_ASSERT_MSG((strcmp(new_me->fpr, generated_fpr) == 0), "strcmp(new_me->fpr, generated_fpr) == 0");
  38.136 @@ -78,7 +121,7 @@
  38.137      TEST_ASSERT_MSG((new_me->user_id), "new_me->user_id");
  38.138      TEST_ASSERT_MSG((new_me->comm_type == PEP_ct_pEp), "new_me->comm_type == PEP_ct_pEp");
  38.139      
  38.140 -    char* default_own_id = NULL;
  38.141 +    default_own_id = NULL;
  38.142      status = get_userid_alias_default(session, own_user_id, &default_own_id);
  38.143      if (status == PEP_CANNOT_FIND_ALIAS) {
  38.144          // Ok, we presume our own id above is the default (should be true if there was no existing DB as in test env)
  38.145 @@ -90,16 +133,15 @@
  38.146      cout << "PASS: myself() retrieved the correct fpr, username and default user id" << endl << endl;
  38.147  
  38.148      free_identity(new_me);
  38.149 -     
  38.150 -    cout << "****************************************************************************************" << endl;
  38.151 -    cout << "* I: 3. myself() on id with no input fpr, a different user_id, and a record in the DB" << endl;
  38.152 -    cout << "****************************************************************************************" << endl << endl;
  38.153 +}
  38.154  
  38.155 -    const char* alias_id = "Huss Es El Mejor Presidente Del Mundo!";
  38.156 +void NewUpdateIdAndMyselfTests::myself_no_input_fpr_diff_user_id_w_record() {
  38.157 +    PEP_STATUS status = PEP_STATUS_OK;
  38.158 +    alias_id = strdup("Huss Es El Mejor Presidente Del Mundo!");
  38.159  
  38.160 -    new_me = new_identity(uniqname, NULL, alias_id, NULL);
  38.161 +    pEp_identity* new_me = new_identity(uniqname, NULL, alias_id, NULL);
  38.162      status = myself(session, new_me);
  38.163 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.164 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.165      
  38.166      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.167      TEST_ASSERT_MSG((strcmp(new_me->fpr, generated_fpr) == 0), "strcmp(new_me->fpr, generated_fpr) == 0");
  38.168 @@ -112,30 +154,29 @@
  38.169      char* tmp_def = NULL;
  38.170      
  38.171      status = get_userid_alias_default(session, alias_id, &tmp_def);
  38.172 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.173 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.174      TEST_ASSERT_MSG((strcmp(tmp_def, default_own_id) == 0), "strcmp(tmp_def, default_own_id) == 0");
  38.175  
  38.176      cout << "PASS: myself() retrieved the correct fpr, username and default user id, and put the right alias in for the default";
  38.177      cout << endl << endl;
  38.178      
  38.179      free(tmp_def);
  38.180 -    free_identity(new_me);
  38.181 +    free_identity(new_me); 
  38.182 +}
  38.183  
  38.184 -    cout << "****************************************************************************************" << endl;
  38.185 -    cout << "* I: 4. myself(), replace fpr" << endl;
  38.186 -    cout << "****************************************************************************************" << endl << endl;
  38.187 -
  38.188 -    new_me = new_identity(uniqname, NULL, alias_id, start_username);
  38.189 +void NewUpdateIdAndMyselfTests::myself_replace_fpr() {
  38.190 +    PEP_STATUS status = PEP_STATUS_OK;
  38.191 +    pEp_identity* new_me = new_identity(uniqname, NULL, alias_id, start_username);
  38.192      status = generate_keypair(session, new_me);
  38.193      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.194      
  38.195      cout << "Generated fingerprint ";
  38.196      cout << new_me->fpr << "\n";
  38.197  
  38.198 -    char* new_fpr = strdup(new_me->fpr);
  38.199 +    new_fpr = strdup(new_me->fpr);
  38.200  
  38.201      status = set_own_key(session, new_me, new_fpr);
  38.202 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.203 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.204      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.205      TEST_ASSERT_MSG((strcmp(new_me->fpr, generated_fpr) != 0), "strcmp(new_me->fpr, generated_fpr) != 0");
  38.206      TEST_ASSERT_MSG((strcmp(new_me->fpr, new_fpr) == 0), "strcmp(new_me->fpr, new_fpr) == 0");
  38.207 @@ -154,21 +195,21 @@
  38.208      new_me->fpr = strdup(generated_fpr);
  38.209      new_me->comm_type = PEP_ct_unknown;
  38.210      status = set_own_key(session, new_me, generated_fpr);
  38.211 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.212 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.213      TEST_ASSERT_MSG((strcmp(new_me->fpr, generated_fpr) == 0), "strcmp(new_me->fpr, generated_fpr) == 0");
  38.214 -    TEST_ASSERT_MSG((new_me->comm_type == PEP_ct_pEp), "new_me->comm_type == PEP_ct_pEp");
  38.215 -    
  38.216 -    cout << "****************************************************************************************" << endl;
  38.217 -    cout << "* I: 5. myself(), replace fpr, revoke key" << endl;
  38.218 -    cout << "****************************************************************************************" << endl << endl;
  38.219 +    TEST_ASSERT_MSG((new_me->comm_type == PEP_ct_pEp), "new_me->comm_type == PEP_ct_pEp");    
  38.220 +    free_identity(new_me);
  38.221 +}
  38.222  
  38.223 +void NewUpdateIdAndMyselfTests::myself_replace_fpr_revoke_key() {
  38.224 +    PEP_STATUS status = PEP_STATUS_OK;
  38.225      status = revoke_key(session, generated_fpr, "Because it's fun");
  38.226      TEST_ASSERT (status == PEP_STATUS_OK);
  38.227      
  38.228 -    new_me = new_identity(uniqname, NULL, alias_id, start_username);
  38.229 +    pEp_identity* new_me = new_identity(uniqname, NULL, alias_id, start_username);
  38.230      
  38.231      status = set_own_key(session, new_me, new_fpr);
  38.232 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.233 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.234      TEST_ASSERT_MSG((new_me->fpr), "new_me->fpr");
  38.235      TEST_ASSERT_MSG((strcmp(new_me->fpr, generated_fpr) != 0), "strcmp(new_me->fpr, generated_fpr) != 0");
  38.236      TEST_ASSERT_MSG((new_me->username), "new_me->username");
  38.237 @@ -180,14 +221,10 @@
  38.238      
  38.239      cout << "PASS: myself() retrieved the new fpr, username and default user id, and put the right alias in for the default";
  38.240      cout << endl << endl;
  38.241 -        
  38.242 -    cout << "***********************************************************************" << endl;
  38.243 -    cout << "* Section II. update_identity()" << endl;
  38.244 -    cout << "***********************************************************************" << endl << endl;
  38.245 +    free_identity(new_me);
  38.246 +}
  38.247  
  38.248 -    cout << "****************************************************************************************" << endl;
  38.249 -    cout << "* II: 1. update_identity() - get identity with matching address and user_id and username" << endl;
  38.250 -    cout << "****************************************************************************************" << endl << endl;    
  38.251 +void NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_username() {
  38.252      // 1. create original identity
  38.253      const char* alex_address = "pep.test.alexander@peptest.ch";
  38.254      const char* alex_fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
  38.255 @@ -201,13 +238,13 @@
  38.256      pEp_identity* alex = new_identity(alex_address, alex_fpr, alex_userid, alex_username);
  38.257  
  38.258      // 2. set identity
  38.259 -    status = set_identity(session, alex);
  38.260 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.261 +    PEP_STATUS status = set_identity(session, alex);
  38.262 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.263      free_identity(alex);
  38.264              
  38.265      alex = new_identity(alex_address, NULL, alex_userid, alex_username); 
  38.266      status = update_identity(session, alex);
  38.267 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.268 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.269      TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.270      TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.271      TEST_ASSERT_MSG((alex->username), "alex->username");
  38.272 @@ -220,17 +257,47 @@
  38.273  
  38.274      cout << "PASS: update_identity() correctly retrieved extant record with matching address, id, and username" << endl << endl;
  38.275      free_identity(alex);
  38.276 +}
  38.277  
  38.278 -    cout << "****************************************************************************************" << endl;
  38.279 -    cout << "* II: 2. update_identity() - get identity with matching address and user_id and new username" << endl;
  38.280 -    cout << "****************************************************************************************" << endl << endl;    
  38.281 +void NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_new_username() {
  38.282 +    PEP_STATUS status = PEP_STATUS_OK;
  38.283 +        
  38.284 +    const string alex_pub_key = slurp("test_keys/pub/pep.test.alexander-0x26B54E4E_pub.asc");
  38.285 +    
  38.286 +    PEP_STATUS statuspub = import_key(session, alex_pub_key.c_str(), alex_pub_key.length(), NULL);
  38.287 +    TEST_ASSERT_MSG((statuspub == PEP_TEST_KEY_IMPORT_SUCCESS), "statuspub == PEP_STATUS_OK");
  38.288  
  38.289 -    const char* new_username = "Test Patchy";
  38.290 +    pEp_identity* alex = new_identity(alex_address, alex_fpr, alex_userid, alex_username);
  38.291 +
  38.292 +    // 2. set identity
  38.293 +    status = set_identity(session, alex);
  38.294 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.295 +    free_identity(alex);
  38.296              
  38.297 -    alex = new_identity(alex_address, NULL, alex_userid, new_username);
  38.298 -    cout << "Timing is everything" << endl; 
  38.299 +    alex = new_identity(alex_address, NULL, alex_userid, alex_username); 
  38.300      status = update_identity(session, alex);
  38.301 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.302 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.303 +    TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.304 +    TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.305 +    TEST_ASSERT_MSG((alex->username), "alex->username");
  38.306 +    TEST_ASSERT_MSG((strcmp(alex->username, alex_username) == 0), "strcmp(alex->username, alex_username) == 0");
  38.307 +    TEST_ASSERT_MSG((alex->user_id), "alex->user_id");
  38.308 +    TEST_ASSERT_MSG((strcmp(alex->user_id, alex_userid) == 0), "strcmp(alex->user_id, alex_userid) == 0");
  38.309 +    TEST_ASSERT_MSG((!alex->me), "!alex->me"); 
  38.310 +    TEST_ASSERT_MSG((alex->comm_type == PEP_ct_OpenPGP_unconfirmed), "alex->comm_type == PEP_ct_OpenPGP_unconfirmed");
  38.311 +    TEST_ASSERT_MSG((strcmp(alex->address, alex_address) == 0), "strcmp(alex->address, alex_address) == 0");
  38.312 +
  38.313 +    cout << "PASS: update_identity() correctly retrieved extant record with matching address, id, and username" << endl << endl;
  38.314 +    free_identity(alex);
  38.315 +}
  38.316 +
  38.317 +void NewUpdateIdAndMyselfTests::update_identity_w_matching_address_user_id_only() {
  38.318 +    PEP_STATUS status = PEP_STATUS_OK;
  38.319 +    new_username = "Test Patchy";
  38.320 +            
  38.321 +    pEp_identity* alex = new_identity(alex_address, NULL, alex_userid, new_username);
  38.322 +    status = update_identity(session, alex);
  38.323 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.324      TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.325      TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.326      TEST_ASSERT_MSG((alex->username), "alex->username");
  38.327 @@ -241,36 +308,13 @@
  38.328      TEST_ASSERT_MSG((alex->comm_type == PEP_ct_OpenPGP_unconfirmed), "alex->comm_type == PEP_ct_OpenPGP_unconfirmed");
  38.329      TEST_ASSERT_MSG((strcmp(alex->address, alex_address) == 0), "strcmp(alex->address, alex_address) == 0");
  38.330  
  38.331 -    cout << "PASS: update_identity() correctly retrieved extant record with matching address and id, and patched username" << endl << endl;
  38.332      free_identity(alex);
  38.333 +}
  38.334  
  38.335 -    cout << "****************************************************************************************" << endl;
  38.336 -    cout << "* II: 3. update_identity() - get identity with matching address and user_id only" << endl;
  38.337 -    cout << "****************************************************************************************" << endl << endl;    
  38.338 -        
  38.339 -    alex = new_identity(alex_address, NULL, alex_userid, NULL); 
  38.340 -    status = update_identity(session, alex);
  38.341 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.342 -    TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.343 -    TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.344 -    TEST_ASSERT_MSG((alex->username), "alex->username");
  38.345 -    TEST_ASSERT_MSG((strcmp(alex->username, new_username) == 0), "strcmp(alex->username, new_username) == 0");
  38.346 -    TEST_ASSERT_MSG((alex->user_id), "alex->user_id");
  38.347 -    TEST_ASSERT_MSG((strcmp(alex->user_id, alex_userid) == 0), "strcmp(alex->user_id, alex_userid) == 0");
  38.348 -    TEST_ASSERT_MSG((!alex->me), "!alex->me"); 
  38.349 -    TEST_ASSERT_MSG((alex->comm_type == PEP_ct_OpenPGP_unconfirmed), "alex->comm_type == PEP_ct_OpenPGP_unconfirmed");
  38.350 -    TEST_ASSERT_MSG((strcmp(alex->address, alex_address) == 0), "strcmp(alex->address, alex_address) == 0");
  38.351 -
  38.352 -    cout << "PASS: update_identity() correctly retrieved extant record with matching address and id, and patched username" << endl << endl;
  38.353 -    free_identity(alex);
  38.354 -
  38.355 -    cout << "****************************************************************************************" << endl;
  38.356 -    cout << "* II: 4. update_identity() - get identity with just address and username" << endl;
  38.357 -    cout << "****************************************************************************************" << endl << endl;    
  38.358 -
  38.359 -    alex = new_identity(alex_address, NULL, NULL, new_username); 
  38.360 -    status = update_identity(session, alex);
  38.361 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.362 +void NewUpdateIdAndMyselfTests::update_identity_use_address_username_only() {
  38.363 +    pEp_identity* alex = new_identity(alex_address, NULL, NULL, new_username); 
  38.364 +    PEP_STATUS status = update_identity(session, alex);
  38.365 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.366      TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.367      TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.368      TEST_ASSERT_MSG((alex->username), "alex->username");
  38.369 @@ -283,14 +327,12 @@
  38.370  
  38.371      cout << "PASS: update_identity() correctly retrieved extant record with matching address and username" << endl << endl;
  38.372      free_identity(alex);
  38.373 +}
  38.374  
  38.375 -    cout << "****************************************************************************************" << endl;
  38.376 -    cout << "* II: 5. update_identity() with just address " << endl;
  38.377 -    cout << "****************************************************************************************" << endl << endl;
  38.378 -    
  38.379 -    alex = new_identity(alex_address, NULL, NULL, NULL); 
  38.380 -    status = update_identity(session, alex);
  38.381 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.382 +void NewUpdateIdAndMyselfTests::update_identity_use_address_only() {
  38.383 +    pEp_identity* alex = new_identity(alex_address, NULL, NULL, NULL); 
  38.384 +    PEP_STATUS status = update_identity(session, alex);
  38.385 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.386      TEST_ASSERT_MSG((alex->fpr), "alex->fpr");
  38.387      TEST_ASSERT_MSG((strcmp(alex->fpr, alex_fpr) == 0), "strcmp(alex->fpr, alex_fpr) == 0");
  38.388      TEST_ASSERT_MSG((alex->username), "alex->username");
  38.389 @@ -303,15 +345,12 @@
  38.390  
  38.391      cout << "PASS: update_identity() correctly retrieved extant record with just matching address. Retrieved previously patched username." << endl << endl;
  38.392      free_identity(alex);
  38.393 +}
  38.394  
  38.395 -
  38.396 -    cout << "****************************************************************************************" << endl;
  38.397 -    cout << "* II: 6. update_identity() with just address on own identity (only case where this is legal)" << endl;
  38.398 -    cout << "****************************************************************************************" << endl << endl;
  38.399 -    
  38.400 +void NewUpdateIdAndMyselfTests::update_identity_use_address_only_on_own_ident() {
  38.401      pEp_identity* somebody = new_identity(uniqname, NULL, NULL, NULL); 
  38.402 -    status = update_identity(session, somebody);
  38.403 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.404 +    PEP_STATUS status = update_identity(session, somebody);
  38.405 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.406      myself(session, somebody);
  38.407      TEST_ASSERT_MSG((somebody->fpr), "somebody->fpr");
  38.408      TEST_ASSERT_MSG((strcmp(somebody->fpr, new_fpr) == 0), "strcmp(somebody->fpr, new_fpr) == 0");
  38.409 @@ -327,71 +366,28 @@
  38.410      cout << endl << endl;
  38.411  
  38.412      free_identity(somebody);
  38.413 +}
  38.414  
  38.415 -    cout << "****************************************************************************************" << endl;
  38.416 -    cout << "* II: 7. update_identity() for address and user_id that don't exist" << endl;
  38.417 -    cout << "****************************************************************************************" << endl << endl;
  38.418 -
  38.419 -    somebody = new_identity("nope@nope.nope", NULL, "some_user_id", NULL); 
  38.420 -    status = update_identity(session, somebody);
  38.421 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.422 +void NewUpdateIdAndMyselfTests::update_identity_non_existent_user_id_address() {
  38.423 +    pEp_identity* somebody = new_identity("nope@nope.nope", NULL, "some_user_id", NULL); 
  38.424 +    PEP_STATUS status = update_identity(session, somebody);
  38.425 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.426      TEST_ASSERT_MSG((!somebody->fpr), "!somebody->fpr");
  38.427      TEST_ASSERT_MSG((somebody->comm_type == PEP_ct_key_not_found), "somebody->comm_type == PEP_ct_key_not_found");
  38.428      
  38.429      cout << "PASS: update_identity() returns identity with no key and unknown comm type" << endl << endl;
  38.430  
  38.431      free_identity(somebody);
  38.432 -    
  38.433 -    cout << "****************************************************************************************" << endl;
  38.434 -    cout << "* II: 8. update_identity() for address and and username, but non-matching temp user_id" << endl;
  38.435 -    cout << "****************************************************************************************" << endl << endl;
  38.436 +}
  38.437  
  38.438 -    // 1. create identity
  38.439 -    const char* bella_address = "pep.test.bella@peptest.ch";
  38.440 -    const char* bella_fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  38.441 -    const char* bella_userid = "TOFU_pep.test.bella@peptest.ch"; // simulate temp ID
  38.442 -    const char* bella_username = "Annabella the Great";
  38.443 -    const string bella_pub_key = slurp("test_keys/pub/pep.test.bella-0xAF516AAE_pub.asc");
  38.444 -    
  38.445 -    statuspub = import_key(session, bella_pub_key.c_str(), bella_pub_key.length(), NULL);
  38.446 -    TEST_ASSERT_MSG((statuspub == PEP_TEST_KEY_IMPORT_SUCCESS), "statuspub == PEP_STATUS_OK");
  38.447 -
  38.448 -    pEp_identity* bella = new_identity(bella_address, bella_fpr, bella_userid, bella_username);
  38.449 -    
  38.450 -    // 2. set identity
  38.451 -    status = set_identity(session, bella);
  38.452 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.453 -    free_identity(bella);
  38.454 -    
  38.455 -    const char* not_my_userid = "Bad Company";
  38.456 -            
  38.457 -    bella = new_identity(bella_address, NULL, not_my_userid, bella_username); 
  38.458 -    status = update_identity(session, bella);
  38.459 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.460 -    TEST_ASSERT_MSG((bella->fpr), "bella->fpr");
  38.461 -    TEST_ASSERT_MSG((strcmp(bella->fpr, bella_fpr) == 0), "strcmp(bella->fpr, bella_fpr) == 0");
  38.462 -    TEST_ASSERT_MSG((bella->username), "bella->username");
  38.463 -    TEST_ASSERT_MSG((strcmp(bella->username, bella_username) == 0), "strcmp(bella->username, bella_username) == 0");
  38.464 -    TEST_ASSERT_MSG((bella->user_id), "bella->user_id");
  38.465 -    TEST_ASSERT_MSG((strcmp(bella->user_id, not_my_userid) == 0), "strcmp(bella->user_id, not_my_userid) == 0"); // ???
  38.466 -    TEST_ASSERT_MSG((!bella->me), "!bella->me"); 
  38.467 -    TEST_ASSERT_MSG((bella->comm_type == PEP_ct_OpenPGP_unconfirmed), "bella->comm_type == PEP_ct_OpenPGP_unconfirmed");
  38.468 -    TEST_ASSERT_MSG((strcmp(bella->address, bella_address) == 0), "strcmp(bella->address, bella_address) == 0");
  38.469 -
  38.470 -    cout << "PASS: update_identity() correctly retrieved extant record with matching address and username; temp user_id in DB patched" << endl << endl;
  38.471 -    free_identity(bella);
  38.472 -
  38.473 -    cout << "****************************************************************************************" << endl;
  38.474 -    cout << "* II: 9. update_identity() for address, username, and user_id, but no matching record" << endl;
  38.475 -    cout << "****************************************************************************************" << endl << endl;
  38.476 -    
  38.477 +void NewUpdateIdAndMyselfTests::update_identity_address_username_userid_no_record() {
  38.478      const char* rando_name = "Pickley BoofBoof";
  38.479      const char* rando_userid = "Boofy";
  38.480      const char* rando_address = "boof@pickles.org";
  38.481 -    somebody = new_identity(rando_address, NULL, rando_userid, rando_name);
  38.482 -    status = update_identity(session, somebody);
  38.483 +    pEp_identity* somebody = new_identity(rando_address, NULL, rando_userid, rando_name);
  38.484 +    PEP_STATUS status = update_identity(session, somebody);
  38.485  
  38.486 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.487 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.488      TEST_ASSERT_MSG((!somebody->fpr || somebody->fpr[0] == '\0'), "!somebody->fpr || somebody->fpr[0] == '\0'");
  38.489      TEST_ASSERT_MSG((somebody->username), "somebody->username");
  38.490      TEST_ASSERT_MSG((strcmp(somebody->username, rando_name) == 0), "strcmp(somebody->username, rando_name) == 0");
  38.491 @@ -403,18 +399,16 @@
  38.492  
  38.493      cout << "PASS: update_identity() correctly created record with no key" << endl << endl;
  38.494      free_identity(somebody);
  38.495 -    
  38.496 -    cout << "****************************************************************************************" << endl;
  38.497 -    cout << "* II: 10. update_identity() for address, username, but no matching record" << endl;
  38.498 -    cout << "****************************************************************************************" << endl << endl;
  38.499 +}
  38.500  
  38.501 +void NewUpdateIdAndMyselfTests::update_identity_address_username_no_record() {
  38.502      const char* rando2_name = "Pickles BoofyBoof";
  38.503      const char* rando2_address = "boof2@pickles.org";
  38.504 -    somebody = new_identity(rando2_address, NULL, NULL, rando2_name);
  38.505 -    status = update_identity(session, somebody);
  38.506 +    pEp_identity* somebody = new_identity(rando2_address, NULL, NULL, rando2_name);
  38.507 +    PEP_STATUS status = update_identity(session, somebody);
  38.508      const char* expected_rando2_userid = "TOFU_boof2@pickles.org";
  38.509  
  38.510 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.511 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.512      TEST_ASSERT_MSG((!somebody->fpr || somebody->fpr[0] == '\0'), "!somebody->fpr || somebody->fpr[0] == '\0'");
  38.513      TEST_ASSERT_MSG((somebody->username), "somebody->username");
  38.514      TEST_ASSERT_MSG((strcmp(somebody->username, rando2_name) == 0), "strcmp(somebody->username, rando2_name) == 0");
  38.515 @@ -426,33 +420,60 @@
  38.516  
  38.517      cout << "PASS: update_identity() correctly created record with no key" << endl << endl;
  38.518      free_identity(somebody);
  38.519 +}
  38.520  
  38.521 -    cout << "****************************************************************************************" << endl;
  38.522 -    cout << "* II: 11. update_identity() for address only, but multiple matching records" << endl;
  38.523 -    cout << "****************************************************************************************" << endl << endl;
  38.524  
  38.525 +void NewUpdateIdAndMyselfTests::update_identity_address_only_multiple_records() {
  38.526 +    PEP_STATUS status = PEP_STATUS_OK;
  38.527 +    // 1. create identity
  38.528 +    const char* bella_address = "pep.test.bella@peptest.ch";
  38.529 +    const char* bella_fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  38.530 +    const char* bella_userid = "TOFU_pep.test.bella@peptest.ch"; // simulate temp ID
  38.531 +    const char* bella_username = "Annabella the Great";
  38.532 +    const string bella_pub_key = slurp("test_keys/pub/pep.test.bella-0xAF516AAE_pub.asc");
  38.533 +    
  38.534 +    PEP_STATUS statuspub = import_key(session, bella_pub_key.c_str(), bella_pub_key.length(), NULL);
  38.535 +    TEST_ASSERT_MSG((statuspub == PEP_TEST_KEY_IMPORT_SUCCESS), "statuspub == PEP_STATUS_OK");
  38.536 +
  38.537 +    pEp_identity* bella = new_identity(bella_address, bella_fpr, bella_userid, bella_username);
  38.538 +    
  38.539 +    // 2. set identity
  38.540 +    status = set_identity(session, bella);
  38.541 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.542 +    free_identity(bella);
  38.543 +    
  38.544 +    const char* not_my_userid = "Bad Company";
  38.545 +            
  38.546 +    bella = new_identity(bella_address, NULL, not_my_userid, bella_username); 
  38.547 +    status = update_identity(session, bella);
  38.548 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.549 +    TEST_ASSERT_MSG((bella->fpr), "bella->fpr");
  38.550 +    TEST_ASSERT_MSG((strcmp(bella->fpr, bella_fpr) == 0), "strcmp(bella->fpr, bella_fpr) == 0");
  38.551 +    TEST_ASSERT_MSG((bella->username), "bella->username");
  38.552 +    TEST_ASSERT_MSG((strcmp(bella->username, bella_username) == 0), "strcmp(bella->username, bella_username) == 0");
  38.553 +    TEST_ASSERT_MSG((bella->user_id), "bella->user_id");
  38.554 +    TEST_ASSERT_MSG((strcmp(bella->user_id, not_my_userid) == 0), "strcmp(bella->user_id, not_my_userid) == 0"); // ???
  38.555 +    TEST_ASSERT_MSG((!bella->me), "!bella->me"); 
  38.556 +    TEST_ASSERT_MSG((bella->comm_type == PEP_ct_OpenPGP_unconfirmed), "bella->comm_type == PEP_ct_OpenPGP_unconfirmed");
  38.557 +    TEST_ASSERT_MSG((strcmp(bella->address, bella_address) == 0), "strcmp(bella->address, bella_address) == 0");
  38.558 +
  38.559 +    free_identity(bella);
  38.560 +    
  38.561 +    // ???? 
  38.562      const char* bella_id_2 = "Bella2";
  38.563      bella = new_identity(bella_address, NULL, bella_id_2, bella_username);
  38.564      
  38.565 -    // 2. set identity
  38.566      status = set_identity(session, bella);
  38.567 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.568 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.569      free_identity(bella);
  38.570                  
  38.571      bella = new_identity(bella_address, NULL, NULL, NULL); 
  38.572      status = update_identity(session, bella);
  38.573 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.574 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.575  
  38.576 -//    cout << "PASS: update_identity() correctly failed with no matching records (too little info)" << endl << endl;
  38.577 -    
  38.578 -    cout << "****************************************************************************************" << endl;
  38.579 -    cout << "* III: key election " << endl;
  38.580 -    cout << "****************************************************************************************" << endl << endl;
  38.581 +}
  38.582  
  38.583 -    cout << "****************************************************************************************" << endl;
  38.584 -    cout << "* III: 1. key election: get identity for user with expired key" << endl;
  38.585 -    cout << "****************************************************************************************" << endl << endl;
  38.586 -
  38.587 +void NewUpdateIdAndMyselfTests::key_elect_expired_key() {
  38.588      // 1. create identity
  38.589      const char* bernd_address = "bernd.das.brot@darthmama.org";
  38.590      const char* bernd_fpr = "F8CE0F7E24EB190A2FCBFD38D4B088A7CAFAA422";
  38.591 @@ -460,14 +481,14 @@
  38.592      const char* bernd_username = "Bernd das Brot der Ultimative Testkandidat";
  38.593      const string bernd_pub_key = slurp("test_keys/pub/bernd.das.brot-0xCAFAA422_pub.asc");
  38.594      
  38.595 -    statuspub = import_key(session, bernd_pub_key.c_str(), bernd_pub_key.length(), NULL);
  38.596 +    PEP_STATUS statuspub = import_key(session, bernd_pub_key.c_str(), bernd_pub_key.length(), NULL);
  38.597      TEST_ASSERT_MSG((statuspub == PEP_TEST_KEY_IMPORT_SUCCESS), "statuspub == PEP_STATUS_OK");
  38.598  
  38.599      pEp_identity* bernd = new_identity(bernd_address, bernd_fpr, bernd_userid, bernd_username);
  38.600      
  38.601      // 2. set identity
  38.602 -    status = set_identity(session, bernd);
  38.603 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.604 +    PEP_STATUS status = set_identity(session, bernd);
  38.605 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.606      free_identity(bernd);
  38.607                  
  38.608      bernd = new_identity(bernd_address, NULL, bernd_userid, bernd_username); 
  38.609 @@ -484,16 +505,13 @@
  38.610  
  38.611      cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_expired" << endl << endl;
  38.612      free_identity(bernd);
  38.613 +    
  38.614 +}
  38.615  
  38.616 -
  38.617 -    cout << "****************************************************************************************" << endl;
  38.618 -    cout << "* III: 2. key election: get identity for user with only revoked or mistrusted keys " << endl;
  38.619 -    cout << "****************************************************************************************" << endl << endl;
  38.620 -
  38.621 +void NewUpdateIdAndMyselfTests::key_elect_only_revoked_mistrusted() {
  38.622      // Create id with no key
  38.623      cout << "Creating new id with no key for : ";
  38.624 -    char *uniqname_10000 = strdup("AAAAtestuser@testdomain.org");
  38.625 -    srandom(time(NULL));
  38.626 +    char *uniqname_10000 = strdup("AAAAtestfool@testdomain.org");
  38.627      for(int i=0; i < 4;i++)
  38.628          uniqname_10000[i] += random() & 0xf;
  38.629      
  38.630 @@ -507,47 +525,50 @@
  38.631  
  38.632      char* revoke_fpr_arr[3];
  38.633      
  38.634 -    status = generate_keypair(session, revokemaster_3000);
  38.635 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), "status == PEP_STATUS_OK && revokemaster_3000->fpr");
  38.636 +    PEP_STATUS status = generate_keypair(session, revokemaster_3000);
  38.637 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), (string(tl_status_string(status)) + " " + revokemaster_3000->fpr).c_str());
  38.638      revoke_fpr_arr[0] = strdup(revokemaster_3000->fpr);
  38.639      free(revokemaster_3000->fpr);
  38.640      revokemaster_3000->fpr = NULL;
  38.641 +    cout << "revoke_fpr_arr[0] is " << revoke_fpr_arr[0] << endl; 
  38.642      
  38.643      status = generate_keypair(session, revokemaster_3000);
  38.644 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), "status == PEP_STATUS_OK && revokemaster_3000->fpr");
  38.645 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), (string(tl_status_string(status)) + " " + revokemaster_3000->fpr).c_str());
  38.646      revoke_fpr_arr[1] = strdup(revokemaster_3000->fpr);
  38.647      free(revokemaster_3000->fpr);
  38.648      revokemaster_3000->fpr = NULL;
  38.649 +    cout << "revoke_fpr_arr[1] is " << revoke_fpr_arr[1] << endl; 
  38.650      
  38.651      status = generate_keypair(session, revokemaster_3000);
  38.652 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), "status == PEP_STATUS_OK && revokemaster_3000->fpr");
  38.653 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK && revokemaster_3000->fpr), (string(tl_status_string(status)) + " " + revokemaster_3000->fpr).c_str());
  38.654      revoke_fpr_arr[2] = strdup(revokemaster_3000->fpr);
  38.655      free(revokemaster_3000->fpr);
  38.656      revokemaster_3000->fpr = NULL;
  38.657 +    cout << "revoke_fpr_arr[2] is " << revoke_fpr_arr[2] << endl; 
  38.658      
  38.659      cout << "Trust "  << revoke_fpr_arr[2] << " (default for identity) and " << revoke_fpr_arr[0] << endl;
  38.660      
  38.661      free(revokemaster_3000->fpr);
  38.662      revokemaster_3000->fpr = strdup(revoke_fpr_arr[2]);
  38.663      status = trust_personal_key(session, revokemaster_3000);
  38.664 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.665 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.666      status = get_trust(session, revokemaster_3000);
  38.667 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.668 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), "revokemaster_3000->comm_type & PEP_ct_confirmed");
  38.669 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.670 +    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), tl_ct_string(revokemaster_3000->comm_type));
  38.671  
  38.672      free(revokemaster_3000->fpr);
  38.673      revokemaster_3000->fpr = strdup(revoke_fpr_arr[0]);
  38.674      status = trust_personal_key(session, revokemaster_3000);
  38.675 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.676 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.677      status = get_trust(session, revokemaster_3000);
  38.678 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.679 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), "revokemaster_3000->comm_type & PEP_ct_confirmed");
  38.680 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.681 +    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), tl_ct_string(revokemaster_3000->comm_type));
  38.682      
  38.683      status = update_identity(session, revokemaster_3000);
  38.684 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.685 -    TEST_ASSERT_MSG((revokemaster_3000->fpr), "revokemaster_3000->fpr");
  38.686 -    TEST_ASSERT_MSG((strcmp(revokemaster_3000->fpr, revoke_fpr_arr[2]) == 0), "strcmp(revokemaster_3000->fpr, revoke_fpr_arr[2]) == 0");
  38.687 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), "revokemaster_3000->comm_type & PEP_ct_confirmed");
  38.688 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.689 +    TEST_ASSERT_MSG((revokemaster_3000->fpr), revokemaster_3000->fpr);
  38.690 +    TEST_ASSERT_MSG((strcmp(revokemaster_3000->fpr, revoke_fpr_arr[2]) == 0), (string("Expected ") + revoke_fpr_arr[2] + ", Got " + revokemaster_3000->fpr).c_str());
  38.691 +    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), tl_ct_string(revokemaster_3000->comm_type));
  38.692  
  38.693      cout << "update_identity returns the correct identity default." << endl;
  38.694      
  38.695 @@ -560,36 +581,47 @@
  38.696  
  38.697      bool is_revoked;
  38.698      status = key_revoked(session, revokemaster_3000->fpr, &is_revoked);    
  38.699 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.700 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.701      TEST_ASSERT_MSG((is_revoked), "is_revoked");
  38.702  
  38.703      cout << "Success revoking " << revoke_fpr_arr[2] << "!!! get_trust for this fpr gives us " << revokemaster_3000->comm_type << endl;
  38.704 +
  38.705 +//  BAD ASSUMPTION - this only works if we query the trust DB in elect_pubkey, and we don't.    
  38.706 +//    cout << "Now see if update_identity gives us " << revoke_fpr_arr[0] << ", the only trusted key left." << endl;
  38.707 +    status = update_identity(session, revokemaster_3000);
  38.708 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.709 +    TEST_ASSERT_MSG((revokemaster_3000->fpr), revokemaster_3000->fpr);
  38.710 +    bool was_key_0 = (strcmp(revokemaster_3000->fpr, revoke_fpr_arr[0]) == 0); 
  38.711 +    bool was_key_1 = (strcmp(revokemaster_3000->fpr, revoke_fpr_arr[1]) == 0); 
  38.712 +    TEST_ASSERT_MSG(was_key_0 || was_key_1,    
  38.713 +                    (string("Expected ") + revoke_fpr_arr[0] + " or " + revoke_fpr_arr[1] + ", Got " + revokemaster_3000->fpr).c_str());                
  38.714 +    if (was_key_0) {               
  38.715 +        TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), tl_ct_string(revokemaster_3000->comm_type));    
  38.716 +    }    
  38.717 +    else {   
  38.718 +        TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_OpenPGP_unconfirmed), tl_ct_string(revokemaster_3000->comm_type));
  38.719 +    }
  38.720 +                
  38.721 +    cout << "Success! So let's mistrust " << revoke_fpr_arr[0] << ", because seriously, that key was so uncool." << endl;
  38.722      
  38.723 -    cout << "Now see if update_identity gives us " << revoke_fpr_arr[0] << ", the only trusted key left." << endl;
  38.724 -    status = update_identity(session, revokemaster_3000);
  38.725 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.726 -    TEST_ASSERT_MSG((revokemaster_3000->fpr), "revokemaster_3000->fpr");
  38.727 -    TEST_ASSERT_MSG((strcmp(revokemaster_3000->fpr, revoke_fpr_arr[0]) == 0), "strcmp(revokemaster_3000->fpr, revoke_fpr_arr[0]) == 0");
  38.728 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type & PEP_ct_confirmed), "revokemaster_3000->comm_type & PEP_ct_confirmed");    
  38.729 -    
  38.730 -    cout << "Success! So let's mistrust it, because seriously, that key was so uncool." << endl;
  38.731 -    
  38.732 +    free(revokemaster_3000->fpr);
  38.733 +    revokemaster_3000->fpr = strdup(revoke_fpr_arr[0]);
  38.734      status = key_mistrusted(session, revokemaster_3000);
  38.735 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.736 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.737  
  38.738      status = get_trust(session, revokemaster_3000);
  38.739 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.740 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type == PEP_ct_mistrusted), "revokemaster_3000->comm_type == PEP_ct_mistrusted");
  38.741 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.742 +    TEST_ASSERT_MSG((revokemaster_3000->comm_type == PEP_ct_mistrusted), tl_ct_string(revokemaster_3000->comm_type));
  38.743      
  38.744      cout << "Success! get_trust for this fpr gives us " << revokemaster_3000->comm_type << endl;
  38.745  
  38.746      cout << "The only fpr left is an untrusted one - let's make sure this is what we get from update_identity." << endl;
  38.747  
  38.748      status = update_identity(session, revokemaster_3000);
  38.749 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.750 -    TEST_ASSERT_MSG((revokemaster_3000->fpr), "revokemaster_3000->fpr");
  38.751 -    TEST_ASSERT_MSG((strcmp(revokemaster_3000->fpr, revoke_fpr_arr[1]) == 0), "strcmp(revokemaster_3000->fpr, revoke_fpr_arr[1]) == 0");
  38.752 -    TEST_ASSERT_MSG((!(revokemaster_3000->comm_type & PEP_ct_confirmed)), "!(revokemaster_3000->comm_type & PEP_ct_confirmed)");    
  38.753 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.754 +    TEST_ASSERT_MSG((revokemaster_3000->fpr), revokemaster_3000->fpr);
  38.755 +    TEST_ASSERT_MSG((strcmp(revokemaster_3000->fpr, revoke_fpr_arr[1]) == 0), (string("Expected ") + revoke_fpr_arr[1] + ", Got " + revokemaster_3000->fpr).c_str());
  38.756 +    TEST_ASSERT_MSG((!(revokemaster_3000->comm_type & PEP_ct_confirmed)), tl_ct_string(revokemaster_3000->comm_type));    
  38.757  
  38.758      cout << "Success! We got " << revoke_fpr_arr[1] << "as the fpr with comm_type " << revokemaster_3000->comm_type << endl;
  38.759      
  38.760 @@ -599,7 +631,7 @@
  38.761      TEST_ASSERT (status == PEP_STATUS_OK);
  38.762  
  38.763      status = key_revoked(session, revokemaster_3000->fpr, &is_revoked);    
  38.764 -    TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.765 +    TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
  38.766      TEST_ASSERT_MSG((is_revoked), "is_revoked");
  38.767      
  38.768      cout << "Success! get_trust for this fpr gives us " << revokemaster_3000->comm_type << endl;
  38.769 @@ -607,17 +639,12 @@
  38.770      cout << "Call update_identity - we expect nothing, plus an error comm type." << endl;
  38.771  
  38.772      status = update_identity(session, revokemaster_3000);
  38.773 -    TEST_ASSERT_MSG((status != PEP_STATUS_OK), "status != PEP_STATUS_OK");
  38.774 -    TEST_ASSERT_MSG((!revokemaster_3000->fpr), "!revokemaster_3000->fpr");
  38.775 -    TEST_ASSERT_MSG((revokemaster_3000->username), "revokemaster_3000->username");
  38.776 -    TEST_ASSERT_MSG((strcmp(revokemaster_3000->user_id, revoke_uuid) == 0), "strcmp(revokemaster_3000->user_id, revoke_uuid) == 0");
  38.777 -    TEST_ASSERT_MSG((revokemaster_3000->comm_type == PEP_ct_key_not_found), "revokemaster_3000->comm_type == PEP_ct_key_not_found");
  38.778 +    TEST_ASSERT_MSG((status != PEP_STATUS_OK), tl_status_string(status));
  38.779 +    TEST_ASSERT_MSG((!revokemaster_3000->fpr), revokemaster_3000->fpr);
  38.780 +    TEST_ASSERT_MSG((revokemaster_3000->username), "No revokemaster_3000->username");
  38.781 +    TEST_ASSERT_MSG((strcmp(revokemaster_3000->user_id, revoke_uuid) == 0), (string("Expected ") + revoke_uuid + ", Got " + revokemaster_3000->user_id).c_str());
  38.782 +    TEST_ASSERT_MSG((revokemaster_3000->comm_type == PEP_ct_key_not_found), tl_ct_string(revokemaster_3000->comm_type));
  38.783      cout << "Success! No key found. The comm_status error was " << revokemaster_3000->comm_type << "and the return status was " << tl_status_string(status) << endl;
  38.784  
  38.785 -    free_identity(revokemaster_3000);
  38.786 -
  38.787 -    cout << "****************************************************************************************" << endl;
  38.788 -    cout << "* III: 100000000. key election: more to come " << endl;
  38.789 -    cout << "****************************************************************************************" << endl << endl;
  38.790 -
  38.791 +    free_identity(revokemaster_3000);    
  38.792  }
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/test/src/engine_tests/NoOwnIdentWritesOnDecryptTests.cc	Mon Apr 01 20:58:40 2019 +0200
    39.3 @@ -0,0 +1,168 @@
    39.4 +// This file is under GNU General Public License 3.0
    39.5 +// see LICENSE.txt
    39.6 +
    39.7 +#include <stdlib.h>
    39.8 +#include <string>
    39.9 +#include <cstring>
   39.10 +#include <cpptest.h>
   39.11 +
   39.12 +#include "pEpEngine.h"
   39.13 +#include "test_util.h"
   39.14 +
   39.15 +#include "EngineTestIndividualSuite.h"
   39.16 +#include "NoOwnIdentWritesOnDecryptTests.h"
   39.17 +
   39.18 +using namespace std;
   39.19 +
   39.20 +NoOwnIdentWritesOnDecryptTests::NoOwnIdentWritesOnDecryptTests(string suitename, string test_home_dir) :
   39.21 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   39.22 +    _to_decrypt = NULL;
   39.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NoOwnIdentWritesOnDecryptTests::check_no_own_ident_writes_on_decrypt"),
   39.24 +                                                                      static_cast<Func>(&NoOwnIdentWritesOnDecryptTests::check_no_own_ident_writes_on_decrypt)));
   39.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NoOwnIdentWritesOnDecryptTests::check_address_only_no_overwrite"),
   39.26 +                                                                      static_cast<Func>(&NoOwnIdentWritesOnDecryptTests::check_address_only_no_overwrite)));
   39.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("NoOwnIdentWritesOnDecryptTests::check_full_info_no_overwrite"),
   39.28 +                                                                      static_cast<Func>(&NoOwnIdentWritesOnDecryptTests::check_full_info_no_overwrite)));
   39.29 +}
   39.30 +
   39.31 +NoOwnIdentWritesOnDecryptTests::~NoOwnIdentWritesOnDecryptTests() {
   39.32 +    free_message(_to_decrypt);
   39.33 +}
   39.34 +
   39.35 +void NoOwnIdentWritesOnDecryptTests::check_no_own_ident_writes_on_decrypt() {
   39.36 +    // This is a weird case - it is NOT a test case, it's just abusing the environment to
   39.37 +    // set _to_decrypt without polluting test keyrings for later tests.
   39.38 +    message* msg = new_message(PEP_dir_outgoing);
   39.39 +    pEp_identity* sender = NULL;
   39.40 +    pEp_identity* me_recip = NULL;
   39.41 +    pEp_identity* other_recip = NULL;
   39.42 +    
   39.43 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));
   39.44 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc"));	
   39.45 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"));
   39.46 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-carol-0x42A85A42_pub.asc"));
   39.47 +    
   39.48 +    sender = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, "Alice");
   39.49 +    set_own_key(session, sender, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97");
   39.50 +    myself(session, sender);
   39.51 +    
   39.52 +    me_recip = new_identity("pep.test.bob@pep-project.org", NULL, "Bob_is_hot", "Hot Bob");
   39.53 +    other_recip = new_identity("pep-test-carol@pep-project.org", NULL, "Carol_loves_me", "Carol Loves Alice");
   39.54 +
   39.55 +    identity_list* to_list = new_identity_list(other_recip);
   39.56 +    identity_list_add(to_list, me_recip);
   39.57 +    
   39.58 +    msg->from = sender;
   39.59 +    msg->to = to_list;
   39.60 +    
   39.61 +    msg->shortmsg = strdup("just a message");
   39.62 +    msg->longmsg = strdup("a really dumb message");
   39.63 +    
   39.64 +    message* enc_msg = NULL;
   39.65 +    
   39.66 +    PEP_STATUS status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   39.67 +    TEST_ASSERT(status == PEP_STATUS_OK);
   39.68 +    free_message(msg);
   39.69 +    enc_msg->dir = PEP_dir_incoming;
   39.70 +    _to_decrypt = enc_msg;
   39.71 +    TEST_ASSERT(true);
   39.72 +}
   39.73 +
   39.74 +void NoOwnIdentWritesOnDecryptTests::check_address_only_no_overwrite() {
   39.75 +    TEST_ASSERT(_to_decrypt);
   39.76 +    message* copy = message_dup(_to_decrypt);
   39.77 +
   39.78 +    free_identity(copy->from);
   39.79 +    
   39.80 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));
   39.81 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"));
   39.82 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/priv/pep-test-bob-0xC9C2EE39_priv.asc"));
   39.83 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-carol-0x42A85A42_pub.asc"));
   39.84 +    
   39.85 +    const char* bob_name = "STOP MESSING WITH ME ALICE";
   39.86 +    const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
   39.87 +    pEp_identity* me = new_identity("pep.test.bob@pep-project.org", NULL, PEP_OWN_USERID, bob_name);
   39.88 +    PEP_STATUS status = set_own_key(session, me, bob_fpr);
   39.89 +    TEST_ASSERT(status == PEP_STATUS_OK);
   39.90 +    status = myself(session, me);
   39.91 +    TEST_ASSERT(status == PEP_STATUS_OK);
   39.92 +    free_identity(me);
   39.93 +    me = NULL;
   39.94 +    
   39.95 +    copy->from = new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL);
   39.96 +    pEp_identity* bob_ident = copy->to->next->ident;
   39.97 +    free(bob_ident->fpr);
   39.98 +    free(bob_ident->user_id);
   39.99 +    bob_ident->fpr = NULL;
  39.100 +    bob_ident->user_id = NULL;
  39.101 +    
  39.102 +    // yes, I know the test keeps the "old" user_id for carol, but it's irrelevant here/
  39.103 +
  39.104 +    message* dec_msg = NULL;
  39.105 +    stringlist_t* keylist = NULL;
  39.106 +    PEP_decrypt_flags_t flags = 0;
  39.107 +    PEP_rating rating = PEP_rating_undefined;
  39.108 +    
  39.109 +    status = decrypt_message(session, copy, &dec_msg, &keylist, &rating, &flags);    
  39.110 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.111 +    TEST_ASSERT(strcmp(dec_msg->to->next->ident->username, "Hot Bob") == 0);
  39.112 +    
  39.113 +    // Make sure Alice calling Bob hot doesn't infiltrate his DB
  39.114 +    status = get_identity(session, "pep.test.bob@pep-project.org", PEP_OWN_USERID, &me);
  39.115 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.116 +    TEST_ASSERT(me);
  39.117 +    TEST_ASSERT(strcmp(me->username, bob_name) == 0);
  39.118 +    TEST_ASSERT(strcmp(me->fpr, bob_fpr) == 0);
  39.119 +    free_identity(me);
  39.120 +    free_message(dec_msg);
  39.121 +    free_message(copy);
  39.122 +}
  39.123 +
  39.124 +void NoOwnIdentWritesOnDecryptTests::check_full_info_no_overwrite() {
  39.125 +    TEST_ASSERT(_to_decrypt);
  39.126 +    message* copy = message_dup(_to_decrypt);
  39.127 +
  39.128 +    free_identity(copy->from);
  39.129 +    
  39.130 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"));
  39.131 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"));
  39.132 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/priv/pep-test-bob-0xC9C2EE39_priv.asc"));
  39.133 +    TEST_ASSERT(slurp_and_import_key(session, "test_keys/pub/pep-test-carol-0x42A85A42_pub.asc"));
  39.134 +    
  39.135 +    const char* bob_name = "STOP MESSING WITH ME ALICE";
  39.136 +    const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
  39.137 +    pEp_identity* me = new_identity("pep.test.bob@pep-project.org", NULL, PEP_OWN_USERID, bob_name);
  39.138 +    PEP_STATUS status = set_own_key(session, me, bob_fpr);
  39.139 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.140 +    status = myself(session, me);
  39.141 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.142 +    free_identity(me);
  39.143 +    me = NULL;
  39.144 +    
  39.145 +    copy->from = new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL);
  39.146 +    pEp_identity* bob_ident = copy->to->next->ident;
  39.147 +    free(bob_ident->user_id);
  39.148 +    bob_ident->user_id = strdup(PEP_OWN_USERID);
  39.149 +    bob_ident->me = true;
  39.150 +    
  39.151 +    // yes, I know the test keeps the "old" user_id for carol, but it's irrelevant here
  39.152 +    message* dec_msg = NULL;
  39.153 +    stringlist_t* keylist = NULL;
  39.154 +    PEP_decrypt_flags_t flags = 0;
  39.155 +    PEP_rating rating = PEP_rating_undefined;
  39.156 +    
  39.157 +    status = decrypt_message(session, copy, &dec_msg, &keylist, &rating, &flags);    
  39.158 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.159 +    TEST_ASSERT(strcmp(dec_msg->to->next->ident->username, "Hot Bob") == 0);
  39.160 +    
  39.161 +    // Make sure Alice calling Bob hot doesn't infiltrate his DB
  39.162 +    status = get_identity(session, "pep.test.bob@pep-project.org", PEP_OWN_USERID, &me);
  39.163 +    TEST_ASSERT(status == PEP_STATUS_OK);
  39.164 +    TEST_ASSERT(me);
  39.165 +    TEST_ASSERT(strcmp(me->username, bob_name) == 0);
  39.166 +    TEST_ASSERT(strcmp(me->fpr, bob_fpr) == 0);
  39.167 +    free_identity(me);
  39.168 +    free_message(dec_msg);
  39.169 +
  39.170 +    free_message(copy);
  39.171 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/src/engine_tests/OwnIdentitiesRetrieveTests.cc	Mon Apr 01 20:58:40 2019 +0200
    40.3 @@ -0,0 +1,51 @@
    40.4 +// This file is under GNU General Public License 3.0
    40.5 +// see LICENSE.txt
    40.6 +
    40.7 +#include <stdlib.h>
    40.8 +#include <string>
    40.9 +
   40.10 +#include "pEpEngine.h"
   40.11 +#include "keymanagement.h"
   40.12 +
   40.13 +#include <cpptest.h>
   40.14 +#include "EngineTestIndividualSuite.h"
   40.15 +#include "OwnIdentitiesRetrieveTests.h"
   40.16 +
   40.17 +using namespace std;
   40.18 +
   40.19 +OwnIdentitiesRetrieveTests::OwnIdentitiesRetrieveTests(string suitename, string test_home_dir) :
   40.20 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   40.21 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("OwnIdentitiesRetrieveTests::check_own_identities_retrieve"),
   40.22 +                                                                      static_cast<Func>(&OwnIdentitiesRetrieveTests::check_own_identities_retrieve)));
   40.23 +}
   40.24 +
   40.25 +void OwnIdentitiesRetrieveTests::check_own_identities_retrieve() {
   40.26 +    stringlist_t* keylist = NULL;
   40.27 +    PEP_STATUS status = own_keys_retrieve(session, &keylist);
   40.28 +    TEST_ASSERT(keylist == NULL);
   40.29 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.30 +
   40.31 +    identity_list* id_list = NULL;
   40.32 +    status = own_identities_retrieve(session, &id_list);
   40.33 +    TEST_ASSERT(id_list == NULL || !(id_list->ident));
   40.34 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.35 +    
   40.36 +    pEp_identity* me = new_identity("krista_b@darthmama.cool", NULL, "MyOwnId", "Krista B.");
   40.37 +    status = myself(session, me);
   40.38 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.39 +    TEST_ASSERT(me->fpr);
   40.40 +    
   40.41 +    // Ok, there's a me identity in the DB.
   40.42 +    // Call the naughty function.
   40.43 +    
   40.44 +    status = own_keys_retrieve(session, &keylist);
   40.45 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.46 +    TEST_ASSERT(keylist);
   40.47 +    TEST_ASSERT(keylist->value);
   40.48 +    cout << keylist->value << endl;
   40.49 +
   40.50 +    status = own_identities_retrieve(session, &id_list);
   40.51 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.52 +    TEST_ASSERT(id_list);
   40.53 +    TEST_ASSERT(id_list->ident);    
   40.54 +}
    41.1 --- a/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Thu Feb 07 16:02:11 2019 +0100
    41.2 +++ b/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Mon Apr 01 20:58:40 2019 +0200
    41.3 @@ -173,6 +173,10 @@
    41.4      
    41.5      int i = 0;
    41.6      
    41.7 +    if (keys->next)
    41.8 +    dedup_stringlist(keys->next);
    41.9 +;
   41.10 +    
   41.11      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   41.12      {
   41.13          if (i == 0) {
   41.14 @@ -287,6 +291,9 @@
   41.15      
   41.16      i = 0;
   41.17      
   41.18 +    if (keys->next)
   41.19 +        dedup_stringlist(keys->next);
   41.20 +    
   41.21      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   41.22      {
   41.23          if (i == 0) {
   41.24 @@ -403,6 +410,10 @@
   41.25      
   41.26      i = 0;
   41.27      
   41.28 +    if (keys->next)
   41.29 +    dedup_stringlist(keys->next);
   41.30 +;
   41.31 +    
   41.32      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   41.33      {
   41.34          if (i == 0) {
    42.1 --- a/test/src/engine_tests/StringlistTests.cc	Thu Feb 07 16:02:11 2019 +0100
    42.2 +++ b/test/src/engine_tests/StringlistTests.cc	Mon Apr 01 20:58:40 2019 +0200
    42.3 @@ -19,6 +19,8 @@
    42.4      EngineTestSuite::EngineTestSuite(suitename, test_home_dir) {            
    42.5      add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StringlistTests::check_stringlists"),
    42.6                                                                        static_cast<Func>(&StringlistTests::check_stringlists)));
    42.7 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StringlistTests::check_dedup_stringlist"),
    42.8 +                                                                      static_cast<Func>(&StringlistTests::check_dedup_stringlist)));
    42.9  }
   42.10  
   42.11  void StringlistTests::check_stringlists() {
   42.12 @@ -119,3 +121,116 @@
   42.13      
   42.14      cout << "done.\n";
   42.15  }
   42.16 +
   42.17 +void StringlistTests::check_dedup_stringlist() {
   42.18 +    const char* str1 = "Your Mama";
   42.19 +    const char* str2 = "And your Papa";
   42.20 +    const char* str3 = "And your little dog too!";
   42.21 +    const char* str4 = "Meh";
   42.22 +    
   42.23 +    stringlist_t* s_list = NULL;
   42.24 +    dedup_stringlist(s_list);
   42.25 +    TEST_ASSERT(s_list == NULL);
   42.26 +    
   42.27 +    s_list = new_stringlist(NULL);
   42.28 +    dedup_stringlist(s_list);    
   42.29 +    TEST_ASSERT(s_list->value == NULL);
   42.30 +    
   42.31 +    stringlist_add(s_list, str1);
   42.32 +    dedup_stringlist(s_list);
   42.33 +    TEST_ASSERT(s_list->value);
   42.34 +    TEST_ASSERT(strcmp(s_list->value, str1) == 0);
   42.35 +    TEST_ASSERT(!s_list->next);
   42.36 +
   42.37 +    // Add same value
   42.38 +    stringlist_add(s_list, str1);
   42.39 +    dedup_stringlist(s_list);
   42.40 +    TEST_ASSERT(s_list->value);
   42.41 +    TEST_ASSERT(strcmp(s_list->value, str1) == 0);
   42.42 +    TEST_ASSERT(!s_list->next);
   42.43 +
   42.44 +    stringlist_add(s_list, str1);
   42.45 +    stringlist_add(s_list, str2);
   42.46 +    dedup_stringlist(s_list);
   42.47 +    TEST_ASSERT(s_list->value);
   42.48 +    TEST_ASSERT(strcmp(s_list->value, str1) == 0);
   42.49 +    TEST_ASSERT(s_list->next);
   42.50 +    TEST_ASSERT(!s_list->next->next);
   42.51 +    TEST_ASSERT(s_list->next->value);
   42.52 +    TEST_ASSERT(strcmp(s_list->next->value, str2) == 0);    
   42.53 +
   42.54 +    free_stringlist(s_list);
   42.55 +    s_list = new_stringlist(str1);
   42.56 +    
   42.57 +    stringlist_add(s_list, str1);
   42.58 +    stringlist_add(s_list, str1);
   42.59 +    stringlist_add(s_list, str1);
   42.60 +    stringlist_add(s_list, str1);
   42.61 +    stringlist_add(s_list, str1);
   42.62 +    stringlist_add(s_list, str1);
   42.63 +    stringlist_add(s_list, str1);
   42.64 +    stringlist_add(s_list, str1);
   42.65 +    stringlist_add(s_list, str1);
   42.66 +    stringlist_add(s_list, str1);
   42.67 +    stringlist_add(s_list, str1);
   42.68 +    stringlist_add(s_list, str1);
   42.69 +    stringlist_add(s_list, str1);
   42.70 +    stringlist_add(s_list, str1);
   42.71 +    stringlist_add(s_list, str1);
   42.72 +    dedup_stringlist(s_list);
   42.73 +    TEST_ASSERT(s_list->value);
   42.74 +    TEST_ASSERT(strcmp(s_list->value, str1) == 0);
   42.75 +    TEST_ASSERT(!s_list->next);
   42.76 +
   42.77 +    free_stringlist(s_list);
   42.78 +    s_list = new_stringlist(str1);
   42.79 +
   42.80 +    stringlist_add(s_list, str1);
   42.81 +    stringlist_add(s_list, str1);
   42.82 +    stringlist_add(s_list, str1);
   42.83 +    stringlist_add(s_list, str1);
   42.84 +    stringlist_add(s_list, str1);
   42.85 +    stringlist_add(s_list, str1);
   42.86 +    stringlist_add(s_list, str1);
   42.87 +    stringlist_add(s_list, str1);
   42.88 +    stringlist_add(s_list, str1);
   42.89 +    stringlist_add(s_list, str1);
   42.90 +    stringlist_add(s_list, str1);
   42.91 +    stringlist_add(s_list, str1);
   42.92 +    stringlist_add(s_list, str1);
   42.93 +    stringlist_add(s_list, str2);
   42.94 +    stringlist_add(s_list, str1);
   42.95 +    dedup_stringlist(s_list);
   42.96 +    TEST_ASSERT(s_list->value);
   42.97 +    TEST_ASSERT(strcmp(s_list->value, str1) == 0);
   42.98 +    TEST_ASSERT(s_list->next);
   42.99 +    TEST_ASSERT(!s_list->next->next);
  42.100 +    TEST_ASSERT(s_list->next->value);
  42.101 +    TEST_ASSERT(strcmp(s_list->next->value, str2) == 0);    
  42.102 +
  42.103 +    free_stringlist(s_list);
  42.104 +    s_list = new_stringlist(str3);
  42.105 +
  42.106 +    stringlist_add(s_list, str2);
  42.107 +    stringlist_add(s_list, str3);
  42.108 +    stringlist_add(s_list, str1);
  42.109 +    stringlist_add(s_list, str3);
  42.110 +    stringlist_add(s_list, str2);
  42.111 +    stringlist_add(s_list, str1);
  42.112 +    stringlist_add(s_list, str4);
  42.113 +    stringlist_add(s_list, str3);
  42.114 +
  42.115 +    dedup_stringlist(s_list);
  42.116 +    TEST_ASSERT(s_list->next);
  42.117 +    TEST_ASSERT(s_list->next->next);
  42.118 +    TEST_ASSERT(s_list->next->next->next);
  42.119 +    TEST_ASSERT(!s_list->next->next->next->next);
  42.120 +    TEST_ASSERT(s_list->value);
  42.121 +    TEST_ASSERT(strcmp(s_list->value, str3) == 0);    
  42.122 +    TEST_ASSERT(s_list->next->value);
  42.123 +    TEST_ASSERT(strcmp(s_list->next->value, str2) == 0);    
  42.124 +    TEST_ASSERT(s_list->next->next->value);
  42.125 +    TEST_ASSERT(strcmp(s_list->next->next->value, str1) == 0);    
  42.126 +    TEST_ASSERT(s_list->next->next->next->value);
  42.127 +    TEST_ASSERT(strcmp(s_list->next->next->next->value, str4) == 0);    
  42.128 +}
    43.1 --- a/test/src/util/test_util.cc	Thu Feb 07 16:02:11 2019 +0100
    43.2 +++ b/test/src/util/test_util.cc	Mon Apr 01 20:58:40 2019 +0200
    43.3 @@ -381,6 +381,18 @@
    43.4      }
    43.5  }
    43.6  
    43.7 +std::string tl_ident_flags_String(identity_flags_t fl) {
    43.8 +    std::string retval;
    43.9 +    if (fl & PEP_idf_not_for_sync)   // don't use this identity for sync
   43.10 +        retval += " PEP_idf_not_for_sync";
   43.11 +    if (fl & PEP_idf_list)           // identity of list of persons
   43.12 +        retval += " PEP_idf_list";
   43.13 +    if (fl & PEP_idf_devicegroup)
   43.14 +        retval += "PEP_idf_devicegroup";
   43.15 +    if (retval.empty())
   43.16 +        return std::string("PEP_idf_OMGWTFBBQ");
   43.17 +    return retval;
   43.18 +}
   43.19  bool slurp_and_import_key(PEP_SESSION session, const char* key_filename) {
   43.20      std::string keyfile = slurp(key_filename);
   43.21      if (import_key(session, keyfile.c_str(), keyfile.size(), NULL) != PEP_TEST_KEY_IMPORT_SUCCESS)