sync/devicegroup.fsm
author Krista Bennett <krista@pep-project.org>
Fri, 27 Oct 2017 20:02:41 +0200
branchENGINE-293
changeset 2219 99b05a2f117e
parent 1739 73374beaca6f
child 1749 32084f52dada
child 2287 026ab4dae779
permissions -rw-r--r--
shelving changes
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 // DeviceGroup protocol for p≡p
     5 
     6 // Copyleft (c) 2016, p≡p foundation
     7 
     8 // Written by Volker Birk
     9 
    10 include ./fsm.yml2
    11 
    12 protocol DeviceGroup {
    13     // all messages have a timestamp, time out and are removed after timeout
    14 
    15     broadcast sendBeacon;
    16     broadcast sendGroupUpdate;
    17     broadcast sendUpdateRequest;
    18     unencrypted sendBeacon;
    19 
    20     fsm DeviceState filename=sync {
    21         condition deviceGrouped();
    22         condition keyElectionWon(Identity partner);
    23         condition sameIdentities(Identity a, Identity b);
    24         condition sameKeyAndAddress(Identity a, Identity b);
    25 
    26         state InitState {
    27             on Init {
    28                 if deviceGrouped()
    29                     go Grouped;
    30                 go Sole;
    31             }
    32         }
    33 
    34         state Sole end=1 {
    35             on KeyGen {
    36                 do sendBeacon;
    37                 go SoleWaiting;
    38             }
    39             on CannotDecrypt {
    40                 do sendBeacon;
    41                 go SoleWaiting;
    42             }
    43             on Beacon(Identity partner){
    44                 do sendHandshakeRequest(partner);
    45                 go SoleBeaconed(partner);
    46             }
    47             on HandshakeRequest(Identity partner) {
    48                 do sendHandshakeRequest(partner);
    49                 go HandshakingSole(partner);
    50             }
    51         }
    52 
    53         // copy of sole state with a timeout to enable fast polling for a second
    54         // TODO use more YSLT power here (substates ?) 
    55         state SoleWaiting timeout=60 {
    56             on KeyGen {
    57                 do sendBeacon;
    58             }
    59             on CannotDecrypt {
    60                 do sendBeacon;
    61             }
    62             on Beacon(Identity partner){
    63                 do sendHandshakeRequest(partner);
    64                 go SoleBeaconed(partner);
    65             }
    66             on HandshakeRequest(Identity partner) {
    67                 do sendHandshakeRequest(partner);
    68                 go HandshakingSole(partner);
    69             }
    70             on Timeout go Sole;
    71         }
    72 
    73         state SoleBeaconed timeout=600 (Identity expected) {
    74             on KeyGen{
    75                 do sendBeacon;
    76                 go Sole;
    77             }
    78             on CannotDecrypt{
    79                 do sendBeacon;
    80                 go Sole;
    81             }
    82             on Beacon(Identity partner) {
    83                 do sendHandshakeRequest(partner);
    84                 go SoleBeaconed(partner);
    85             }
    86             on HandshakeRequest(Identity partner) {
    87                 if sameIdentities(partner, expected) {
    88                     // do nothing, to avoid sending handshake request twice 
    89                 } else {
    90                     do sendHandshakeRequest(partner);
    91                 }
    92                 go HandshakingSole(partner);
    93             }
    94             on Timeout go Sole;
    95         }
    96 
    97         state HandshakingSole timeout=600 (Identity expected) {
    98             on Init{
    99                 if keyElectionWon(expected) {
   100                     do notifyInitFormGroup(expected);
   101                 } else {
   102                     do notifyInitAddOurDevice(expected);
   103                 }
   104             }
   105             on HandshakeRejected(Identity partner) {
   106                 do rejectHandshake(partner);
   107                 go Sole;
   108             }
   109             on HandshakeAccepted(Identity partner) {
   110                 if sameIdentities(partner, expected) {
   111                     do acceptHandshake(partner); 
   112                     if keyElectionWon(partner) {
   113                         do makeGroup;
   114                         do sendGroupKeys(partner);
   115                         do renewUUID;
   116                         do notifyAcceptedGroupCreated(partner);
   117                         go Grouped;
   118                     }
   119                     go WaitForGroupKeysSole(partner);
   120                 }
   121                 go Sole;
   122             }
   123             on Cancel go Sole;
   124             on GroupKeys(Identity partner, GroupKeys groupkeys) {
   125                 if keyElectionWon(expected) {
   126                     // not supposed to receive groupkeys - ignore
   127                 } else {
   128                     // UUID changes in between, so we can only check for same address and fpr
   129                     if sameKeyAndAddress(partner, expected) {
   130                         go WaitForAcceptSole(partner, groupkeys);
   131                     }
   132                 }
   133             }
   134             on Timeout {
   135                 do notifyTimeout(expected);
   136                 do sendBeacon;
   137                 go Sole;
   138             }
   139         }
   140     
   141         state WaitForGroupKeysSole timeout=600 (Identity expected) {
   142             on GroupKeys(Identity partner, GroupKeys groupkeys) {
   143                 // UUID changes in between, so we can only check for same address and fpr
   144                 if sameKeyAndAddress(partner, expected) {
   145                     do storeGroupKeys(partner, groupkeys);
   146                     do sendGroupUpdate;
   147                     do renewUUID;
   148                     do notifyAcceptedDeviceAdded(partner);
   149                     go Grouped;
   150                 }
   151             }
   152             on Timeout {
   153                 do notifyTimeout(expected);
   154                 go Sole;
   155             }
   156         }
   157 
   158         state WaitForAcceptSole timeout=600 (Identity expected, GroupKeys groupkeys) {
   159             on HandshakeRejected(Identity partner) {
   160                 do rejectHandshake(partner);
   161                 go Sole;
   162             }
   163             on HandshakeAccepted(Identity partner) {
   164                 // UUID changes in between, so we can only check for same address and fpr
   165                 if sameKeyAndAddress(partner, expected) {
   166                     do acceptHandshake(partner); 
   167                     do storeGroupKeys(partner, groupkeys);
   168                     do sendGroupUpdate;
   169                     do renewUUID;
   170                     do notifyAcceptedDeviceAdded(partner);
   171                     go Grouped;
   172                 }
   173                 go Sole;
   174             }
   175             on Cancel go Sole;
   176             on Timeout {
   177                 do notifyTimeout(expected);
   178                 go Sole;
   179             }
   180         }
   181 
   182         state Grouped end=1 {
   183             on KeyGen
   184                 do sendGroupUpdate;
   185             on CannotDecrypt {
   186                 do sendUpdateRequest;
   187                 do sendBeacon;
   188                 go GroupWaiting;
   189             }
   190             on UpdateRequest
   191                 do sendGroupUpdate;
   192             on Beacon(Identity partner){
   193                 do sendHandshakeRequest(partner);
   194                 go GroupedBeaconed(partner);
   195             }
   196             on HandshakeRequest(Identity partner) {
   197                 do sendHandshakeRequest(partner);
   198                 go HandshakingGrouped(partner);
   199             }
   200             on GroupUpdate(Identity partner, IdentityList keys)
   201                 do storeGroupUpdate(partner, keys);
   202         }
   203 
   204         // copy of grouped state, with a timeout to enable fast poling for a minut
   205         state GroupWaiting timeout=60 {
   206             on KeyGen
   207                 do sendGroupUpdate;
   208             on CannotDecrypt {
   209                 do sendUpdateRequest;
   210                 do sendBeacon;
   211             }
   212             on UpdateRequest
   213                 do sendGroupUpdate;
   214             on Beacon(Identity partner){
   215                 do sendHandshakeRequest(partner);
   216                 go GroupedBeaconed(partner);
   217             }
   218             on HandshakeRequest(Identity partner) {
   219                 do sendHandshakeRequest(partner);
   220                 go HandshakingGrouped(partner);
   221             }
   222             on GroupUpdate(Identity partner, IdentityList keys)
   223                 do storeGroupUpdate(partner, keys);
   224             on Timeout go Grouped;
   225         }
   226 
   227         state GroupedBeaconed timeout=600 (Identity expected){
   228             on KeyGen
   229                 do sendGroupUpdate;
   230             on CannotDecrypt {
   231                 do sendUpdateRequest;
   232                 do sendBeacon;
   233             }
   234             on UpdateRequest
   235                 do sendGroupUpdate;
   236             on Beacon(Identity partner){
   237                 do sendHandshakeRequest(partner);
   238                 go GroupedBeaconed(partner);
   239             }
   240             on HandshakeRequest(Identity partner) {
   241                 if sameIdentities(partner, expected) {
   242                     // do nothing, to avoid sending handshake request twice 
   243                 } else {
   244                     do sendHandshakeRequest(partner);
   245                 }
   246                 go HandshakingGrouped(partner);
   247             }
   248             on GroupUpdate(Identity partner, IdentityList keys)
   249                 do storeGroupUpdate(partner, keys);
   250             on Timeout go Grouped;
   251         }
   252 
   253         state HandshakingGrouped timeout=600 (Identity expected) {
   254             // HandshakeRequest from same group are filtered in receive_sync_msg
   255             on Init{
   256                 if keyElectionWon(expected) {
   257                     do notifyInitAddOtherDevice(partner);
   258                 } else {
   259                     do notifyInitMoveOurDevice(partner);
   260                 }
   261             }
   262             on HandshakeRejected(Identity partner) {
   263                 do rejectHandshake(partner);             // stores rejection of partner
   264                 do sendGroupUpdate;
   265                 go Grouped;
   266             }
   267             on HandshakeAccepted(Identity partner) {
   268                 do acceptHandshake(partner); 
   269                 do sendGroupUpdate;
   270                 if keyElectionWon(partner) {
   271                     do sendGroupKeys(partner);
   272                     do notifyAcceptedDeviceAdded(partner);
   273                     go Grouped;
   274                 }
   275                 go WaitForGroupKeysGrouped(partner);
   276             }
   277             on Cancel go Grouped;
   278             on GroupKeys(Identity partner, GroupKeys groupkeys) {
   279                 if keyElectionWon(expected) {
   280                     // not supposed to receive groupkeys - ignore
   281                 } else {
   282                     // UUID changes in between, so we can only check for same address and fpr
   283                     if sameKeyAndAddress(partner, expected) {
   284                         go WaitForAcceptGrouped(partner, groupkeys);
   285                     }
   286                 }
   287             }
   288             on GroupUpdate(Identity partner, IdentityList keys) {
   289                 do notifyOvertaken(partner);
   290                 do storeGroupUpdate(partner, keys);
   291                 go Grouped;
   292             }
   293             on Timeout {
   294                 do notifyTimeout(expected);
   295                 go Grouped;
   296             }
   297         }
   298 
   299         state WaitForGroupKeysGrouped timeout=600 (Identity expected) {
   300             on GroupKeys(Identity partner, GroupKeys groupkeys) {
   301                 if sameIdentities(partner, expected) {
   302                     do storeGroupKeys(partner, groupkeys);
   303                     do sendGroupUpdate;
   304                     do renewUUID;
   305                     do notifyAcceptedDeviceMoved(partner);
   306                     go Grouped;
   307                 }
   308             }
   309             on GroupUpdate(Identity partner, IdentityList keys) {
   310                 do notifyOvertaken(partner);
   311                 do storeGroupUpdate(partner, keys);
   312                 go Grouped;
   313             }
   314             on Timeout {
   315                 do notifyTimeout(expected);
   316                 go Grouped;
   317             }
   318         }
   319 
   320         state WaitForAcceptGrouped timeout=600 (Identity expected, GroupKeys groupkeys) {
   321             on HandshakeRejected(Identity partner) {
   322                 do rejectHandshake(partner);
   323                 do sendGroupUpdate;
   324                 go Grouped;
   325             }
   326             on HandshakeAccepted(Identity partner) {
   327                 if sameIdentities(partner, expected) {
   328                     do acceptHandshake(partner); 
   329                     do storeGroupKeys(partner, groupkeys);
   330                     do sendGroupUpdate;
   331                     do renewUUID;
   332                     do notifyAcceptedDeviceMoved(partner);
   333                 }
   334                 go Grouped;
   335             }
   336             on Cancel go Grouped;
   337             on GroupUpdate(Identity partner, IdentityList keys) {
   338                 do notifyOvertaken(partner);
   339                 do storeGroupUpdate(partner, keys);
   340                 go Grouped;
   341             }
   342             on Timeout {
   343                 do notifyTimeout(expected);
   344                 go Grouped;
   345             }
   346         }
   347 
   348         tag Init 1;
   349         tag Beacon 2;
   350         tag HandshakeRequest 3;
   351         tag GroupKeys 4;
   352     }
   353 }
   354