make it simple sync
authorVolker Birk <vb@pep-project.org>
Sat, 13 Apr 2019 22:18:57 +0200
branchsync
changeset 3509a9c0c6f31c56
parent 3508 55bada5a0fed
child 3510 98f79218de04
make it simple
sync/gen_message_func.ysl2
sync/gen_messages.ysl2
sync/gen_statemachine.ysl2
sync/sync.fsm
     1.1 --- a/sync/gen_message_func.ysl2	Thu Apr 11 18:57:19 2019 +0200
     1.2 +++ b/sync/gen_message_func.ysl2	Sat Apr 13 22:18:57 2019 +0200
     1.3 @@ -192,11 +192,9 @@
     1.4  ||
     1.5  case «../@name»_PR_«yml:lcase(@name)»:
     1.6      {
     1.7 -        static long sequence = 0;
     1.8 -        msg->choice.«yml:lcase(@name)».header.sequence = ++sequence;
     1.9 -        int message_type = msg->choice.«yml:lcase(@name)».payload.present;
    1.10 +        int message_type = msg->choice.«yml:lcase(@name)».present;
    1.11          switch (message_type) {
    1.12 -            case «@name»__payload_PR_NOTHING:
    1.13 +            case «@name»_PR_NOTHING:
    1.14                  return PEP_ILLEGAL_VALUE;
    1.15  
    1.16              `` apply "message", 2, mode=update_message
    1.17 @@ -209,7 +207,7 @@
    1.18  
    1.19  template "message", mode=update_message {
    1.20      ||
    1.21 -    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    1.22 +    case «../@name»_PR_«yml:mixedCase(@name)»:
    1.23          `` apply "auto"
    1.24          `` apply "field", mode=update_message
    1.25          break;
    1.26 @@ -231,8 +229,8 @@
    1.27              *major = «$fsm/version/@major»;
    1.28              *minor = «$fsm/version/@minor»;
    1.29  
    1.30 -            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».major = major;
    1.31 -            msg->choice.«yml:lcase($fsm/@name)».payload.choice.«yml:mixedCase(../@name)».«@name».minor = minor;
    1.32 +            msg->choice.«yml:lcase($fsm/@name)».choice.«yml:mixedCase(../@name)».«@name».major = major;
    1.33 +            msg->choice.«yml:lcase($fsm/@name)».choice.«yml:mixedCase(../@name)».«@name».minor = minor;
    1.34          }
    1.35  
    1.36          ||
    1.37 @@ -254,7 +252,7 @@
    1.38      choose {
    1.39          when "func:basicType()" // copyable
    1.40          ||
    1.41 -        msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»
    1.42 +        msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»
    1.43                   = session->«$state».«@name»;
    1.44  
    1.45          ||
    1.46 @@ -266,7 +264,7 @@
    1.47              if (!il)
    1.48                  return PEP_OUT_OF_MEMORY;
    1.49              IdentityList_t *_il = IdentityList_from_identity_list(il,
    1.50 -                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»);
    1.51 +                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»);
    1.52              free_identity_list(il);
    1.53              if (!_il)
    1.54                  return PEP_OUT_OF_MEMORY;
    1.55 @@ -277,7 +275,7 @@
    1.56          ||
    1.57          {
    1.58              int result = OCTET_STRING_fromBuf(
    1.59 -                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name»,
    1.60 +                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name»,
    1.61                      (char *) session->«$state».«@name».buf,
    1.62                      session->«$state».«@name».size
    1.63                  );
    1.64 @@ -291,8 +289,8 @@
    1.65  template "fsm", mode=update_state
    1.66  ||
    1.67  case «../@name»_PR_«yml:lcase(@name)»:
    1.68 -    switch (msg->choice.«yml:lcase(@name)».payload.present) {
    1.69 -        case «@name»__payload_PR_NOTHING:
    1.70 +    switch (msg->choice.«yml:lcase(@name)».present) {
    1.71 +        case «@name»_PR_NOTHING:
    1.72              return PEP_ILLEGAL_VALUE;
    1.73  
    1.74          `` apply "message", 2, mode=update_state
    1.75 @@ -306,7 +304,7 @@
    1.76  template "message", mode=update_state {
    1.77      const "message_name", "concat(yml:lcase(substring(@name,1,1)), substring(@name,2))";
    1.78      ||
    1.79 -    case «../@name»__payload_PR_«$message_name»:
    1.80 +    case «../@name»_PR_«$message_name»:
    1.81          `` apply "field", mode=update_state with "message_name", "$message_name"
    1.82          *message_type = «yml:capit($message_name)»;
    1.83          break;
    1.84 @@ -320,14 +318,14 @@
    1.85          when "func:basicType()" // copyable
    1.86          ||
    1.87          session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name» = msg->choice.«yml:lcase(../../@name)»
    1.88 -                .payload.choice.«$message_name».«@name»;
    1.89 +                .choice.«$message_name».«@name»;
    1.90  
    1.91          ||
    1.92          when "@type='IdentityList'"
    1.93          ||
    1.94          {
    1.95              identity_list *il = IdentityList_to_identity_list(
    1.96 -                    &msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name», NULL);
    1.97 +                    &msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name», NULL);
    1.98              if (!il)
    1.99                  return PEP_OUT_OF_MEMORY;
   1.100              IdentityList_t *_il = IdentityList_from_identity_list(il,
   1.101 @@ -341,8 +339,8 @@
   1.102          otherwise // string based
   1.103          ||
   1.104          result = OCTET_STRING_fromBuf(&session->«yml:lcase(../../../@name)»_state.«yml:lcase(../../@name)».«@name»,
   1.105 -                (char *) msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».buf,
   1.106 -                msg->choice.«yml:lcase(../../@name)».payload.choice.«$message_name».«@name».size);
   1.107 +                (char *) msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name».buf,
   1.108 +                msg->choice.«yml:lcase(../../@name)».choice.«$message_name».«@name».size);
   1.109          if (result)
   1.110              return PEP_OUT_OF_MEMORY;
   1.111  
   1.112 @@ -353,7 +351,7 @@
   1.113  template "fsm", mode=impl
   1.114  ||
   1.115  case «../@name»_PR_«yml:lcase(@name)»:
   1.116 -    msg->choice.«yml:lcase(@name)».payload.present = message_type;
   1.117 +    msg->choice.«yml:lcase(@name)».present = message_type;
   1.118          break;
   1.119  
   1.120  ||
     2.1 --- a/sync/gen_messages.ysl2	Thu Apr 11 18:57:19 2019 +0200
     2.2 +++ b/sync/gen_messages.ysl2	Sat Apr 13 22:18:57 2019 +0200
     2.3 @@ -77,14 +77,8 @@
     2.4          }
     2.5  
     2.6          `` apply "message", 0, mode=impl;
     2.7 -        «@name» ::= SEQUENCE {
     2.8 -            header SEQUENCE {
     2.9 -                sequence INTEGER  -- always increases
    2.10 -            },
    2.11 -
    2.12 -            payload CHOICE {
    2.13 -            `` for "message" |>> «yml:mixedCase(@name)» [APPLICATION «@id»] «@name»`if "position()!=last()" > ,`
    2.14 -            }
    2.15 +        «@name» ::= CHOICE {
    2.16 +        `` for "message" |> «yml:mixedCase(@name)» [APPLICATION «@id»] «@name»`if "position()!=last()" > ,`
    2.17          }
    2.18  
    2.19          END
     3.1 --- a/sync/gen_statemachine.ysl2	Thu Apr 11 18:57:19 2019 +0200
     3.2 +++ b/sync/gen_statemachine.ysl2	Sat Apr 13 22:18:57 2019 +0200
     3.3 @@ -410,7 +410,7 @@
     3.4  
     3.5                  switch (message_type) {
     3.6                      // these messages are being broadcasted
     3.7 -                    `` for "fsm/message[@type='broadcast']" |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
     3.8 +                    `` for "fsm/message[@type='broadcast']" |>> case «../@name»_PR_«yml:mixedCase(@name)»:
     3.9                          status = _own_identities_retrieve(session, &channels, PEP_idf_not_for_«yml:lcase(@name)»);
    3.10                          if (status)
    3.11                              goto the_end;
    3.12 @@ -425,7 +425,7 @@
    3.13                          break;
    3.14  
    3.15                      // these go anycast; previously used address is sticky (unicast)
    3.16 -                    `` for "fsm/message[@type='anycast']" |>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    3.17 +                    `` for "fsm/message[@type='anycast']" |>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.18                          if (!session->«yml:lcase(@name)»_state.common.from `> |`|
    3.19                              (session->«yml:lcase(@name)»_state.common.from->flags &
    3.20                              PEP_idf_not_for_«yml:lcase(@name)»)) {
    3.21 @@ -478,8 +478,10 @@
    3.22                      }
    3.23                      memcpy(_data, data, size);
    3.24  
    3.25 +                    stringlist_t *extra = NULL;
    3.26 +
    3.27                      switch (message_type) {
    3.28 -                    `` for "fsm/message[@security='unencrypted']" |>>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    3.29 +                    `` for "fsm/message[@security='unencrypted']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.30                              status = base_prepare_message(
    3.31                                      session,
    3.32                                      li->ident,
    3.33 @@ -498,7 +500,7 @@
    3.34                              m = _m;
    3.35                              break;
    3.36  
    3.37 -                    `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    3.38 +                    `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.39                              status = base_prepare_message(
    3.40                                      session,
    3.41                                      li->ident,
    3.42 @@ -513,7 +515,21 @@
    3.43                                  free(_data);
    3.44                                  goto the_end;
    3.45                              }
    3.46 -                            status = encrypt_message(session, _m, NULL, &m, PEP_enc_PEP, 0);
    3.47 +
    3.48 +                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.49 +                            if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
    3.50 +                                status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.51 +                                goto the_end;
    3.52 +                            }
    3.53 +
    3.54 +                            extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.55 +                            if (extra) {
    3.56 +                                status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
    3.57 +                                free_stringlist(extra);
    3.58 +                            }
    3.59 +                            else {
    3.60 +                                status = PEP_OUT_OF_MEMORY;
    3.61 +                            }
    3.62                              if (status) {
    3.63                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.64                                  goto the_end;
    3.65 @@ -536,7 +552,21 @@
    3.66                                  free(_data);
    3.67                                  goto the_end;
    3.68                              }
    3.69 -                            status = encrypt_message(session, _m, NULL, &m, PEP_enc_PEP, 0);
    3.70 +
    3.71 +                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.72 +                            if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
    3.73 +                                status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.74 +                                goto the_end;
    3.75 +                            }
    3.76 +
    3.77 +                            stringlist_t *extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.78 +                            if (extra) {
    3.79 +                                status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
    3.80 +                                free_stringlist(extra);
    3.81 +                            }
    3.82 +                            else {
    3.83 +                                status = PEP_OUT_OF_MEMORY;
    3.84 +                            }
    3.85                              if (status) {
    3.86                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.87                                  goto the_end;
    3.88 @@ -658,13 +688,13 @@
    3.89      {
    3.90          ||
    3.91          case «../@name»_PR_«yml:lcase(@name)»:
    3.92 -            switch (msg->choice.«yml:lcase(@name)».payload.present) {
    3.93 +            switch (msg->choice.«yml:lcase(@name)».present) {
    3.94          ||
    3.95          if "message[@security='unencrypted']" {
    3.96              |>> // these messages require a detached signature
    3.97              for "message[@security='unencrypted']" {
    3.98              ||
    3.99 -                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
   3.100 +                    case «../@name»_PR_«yml:mixedCase(@name)»:
   3.101                          if (!signature_fpr) {
   3.102                              status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
   3.103                              goto the_end;
   3.104 @@ -679,7 +709,7 @@
   3.105              |>> // these messages must arrive encrypted
   3.106              for "message[@security='untrusted']" {
   3.107              ||
   3.108 -                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
   3.109 +                    case «../@name»_PR_«yml:mixedCase(@name)»:
   3.110                          if (rating < PEP_rating_reliable) {
   3.111                              status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
   3.112                              goto the_end;
   3.113 @@ -694,7 +724,7 @@
   3.114              |>> // these messages must come through a trusted channel
   3.115              for "message[@security='trusted']" {
   3.116              ||
   3.117 -                    case «../@name»__payload_PR_«yml:mixedCase(@name)»:
   3.118 +                    case «../@name»_PR_«yml:mixedCase(@name)»:
   3.119                          if (rating < PEP_rating_trusted) {
   3.120                              status = PEP_«yml:ucase(ancestor::protocol/@name)»_ILLEGAL_MESSAGE;
   3.121                              goto the_end;
   3.122 @@ -719,11 +749,11 @@
   3.123      {
   3.124      ||
   3.125      case «../@name»_PR_«yml:lcase(@name)»: {
   3.126 -        switch (msg->choice.«yml:lcase(@name)».payload.present) {
   3.127 +        switch (msg->choice.«yml:lcase(@name)».present) {
   3.128      ||
   3.129      for "message"
   3.130      ||
   3.131 -            case «../@name»__payload_PR_«yml:mixedCase(@name)»:
   3.132 +            case «../@name»_PR_«yml:mixedCase(@name)»:
   3.133                  ev->event = «@name»;
   3.134                  break;
   3.135      ||
   3.136 @@ -999,7 +1029,7 @@
   3.137          ||
   3.138  
   3.139          «$fsm/@name»_SERVICE_LOG("send message", "«@name»");
   3.140 -        status = send_«$protocol/@name»_message(session, «$fsm/@id», «$fsm/@name»__payload_PR_«yml:mixedCase(@name)»);
   3.141 +        status = send_«$protocol/@name»_message(session, «$fsm/@id», «$fsm/@name»_PR_«yml:mixedCase(@name)»);
   3.142          if (status == PEP_OUT_OF_MEMORY)
   3.143              return out_of_memory;
   3.144          if (status) {
     4.1 --- a/sync/sync.fsm	Thu Apr 11 18:57:19 2019 +0200
     4.2 +++ b/sync/sync.fsm	Sat Apr 13 22:18:57 2019 +0200
     4.3 @@ -37,30 +37,42 @@
     4.4                  if weAreFirst {
     4.5                      send Beacon;
     4.6                  }
     4.7 -                else {
     4.8 +                else /* we are second */ {
     4.9                      do storeChallenge; // partner's challenge
    4.10                      do openTransaction;
    4.11                      do storeTransaction;
    4.12 +                    // second is sending HandshakeRequest
    4.13                      send HandshakeRequest;
    4.14                  }
    4.15              }
    4.16  
    4.17              on HandshakeRequest {
    4.18 -                if challengeAccepted {
    4.19 -                    do storeTransaction;
    4.20 -                    send HandshakeAnswer;
    4.21 -                    if partnerIsGrouped
    4.22 -                        go HandshakingWithGroup;
    4.23 -                    go HandshakingNew;
    4.24 +                if weAreFirst {
    4.25 +                    if challengeAccepted {
    4.26 +                        // first is receiving HandshakeRequest
    4.27 +                        do storeTransaction;
    4.28 +                        // first is sending HandshakeAnswer
    4.29 +                        send HandshakeAnswer;
    4.30 +                        if partnerIsGrouped
    4.31 +                            go HandshakingWithGroup;
    4.32 +                        go HandshakingNewFirst;
    4.33 +                    }
    4.34                  }
    4.35              }
    4.36  
    4.37 -            on HandshakeAnswer
    4.38 -                go HandshakingNew;
    4.39 +            on HandshakeAnswer {
    4.40 +                if weAreFirst {
    4.41 +                    // ignore
    4.42 +                }
    4.43 +                else {
    4.44 +                    // second is receiving HandshakeAnswer
    4.45 +                    go HandshakingNewSecond;
    4.46 +                }
    4.47 +            }
    4.48          }
    4.49  
    4.50          // handshaking without existing Device group
    4.51 -        state HandshakingNew {
    4.52 +        state HandshakingNewFirst {
    4.53              on Init
    4.54                  do showSoleHandshake;
    4.55  
    4.56 @@ -85,17 +97,68 @@
    4.57                  go End;
    4.58              }
    4.59  
    4.60 -            // Accept is Phase1Commit
    4.61 +            // Accept means init Phase1Commit
    4.62              on Accept {
    4.63                  send CommitAcceptForGroup;
    4.64 -                go HandshakingNewPhase1;
    4.65 +                go HandshakingNewPhase1First;
    4.66 +            }
    4.67 +
    4.68 +            // got a CommitAccept from second
    4.69 +            on CommitAccept
    4.70 +                go HandshakingNewPhase2;
    4.71 +        }
    4.72 +
    4.73 +        // handshaking without existing Device group
    4.74 +        state HandshakingNewSecond {
    4.75 +            on Init
    4.76 +                do showSoleHandshake;
    4.77 +
    4.78 +            // Cancel is Rollback
    4.79 +            on Cancel {
    4.80 +                send Rollback;
    4.81 +                go Sole;
    4.82 +            }
    4.83 +
    4.84 +            on Rollback
    4.85 +                go Sole;
    4.86 +
    4.87 +            // Reject is CommitReject
    4.88 +            on Reject {
    4.89 +                send CommitReject;
    4.90 +                do disable;
    4.91 +                go End;
    4.92 +            }
    4.93 +
    4.94 +            on CommitReject {
    4.95 +                do disable;
    4.96 +                go End;
    4.97 +            }
    4.98 +
    4.99 +            // Accept means init Phase1Commit
   4.100 +            on Accept {
   4.101 +                send CommitAccept;
   4.102 +                go HandshakingNewPhase1Second;
   4.103 +            }
   4.104 +
   4.105 +            // got a CommitAccept from first
   4.106 +            on CommitAccept
   4.107 +                go HandshakingNewPhase2;
   4.108 +        }
   4.109 +
   4.110 +        state HandshakingNewPhase1First {
   4.111 +            on Rollback
   4.112 +                go Sole;
   4.113 +            
   4.114 +            on CommitReject {
   4.115 +                do disable;
   4.116 +                go End;
   4.117              }
   4.118  
   4.119              on CommitAccept
   4.120 -                go HandshakingNewPhase1Own;
   4.121 +                go NewGroup;
   4.122          }
   4.123  
   4.124 -        state HandshakingNewPhase1 {
   4.125 +        state HandshakingNewPhase1Second {
   4.126              on Rollback
   4.127                  go Sole;
   4.128              
   4.129 @@ -108,7 +171,7 @@
   4.130                  go NewGroup;
   4.131          }
   4.132  
   4.133 -        state HandshakingNewPhase1Own {
   4.134 +        state HandshakingNewPhase2 {
   4.135              on Cancel {
   4.136                  send Rollback;
   4.137                  go Sole;
   4.138 @@ -200,7 +263,7 @@
   4.139              }
   4.140  
   4.141              on Accept
   4.142 -                go JoinGroup;
   4.143 +                go OwnGroup;
   4.144          }
   4.145  
   4.146          state JoinGroup {
   4.147 @@ -211,6 +274,14 @@
   4.148              }
   4.149          }
   4.150  
   4.151 +        state OwnGroup {
   4.152 +            on GroupKeys {
   4.153 +                send GroupKeys; // first send own keys
   4.154 +                do saveGroupKeys; // then store new group keys
   4.155 +                go Grouped;
   4.156 +            }
   4.157 +        }
   4.158 +
   4.159          state Grouped timeout=off {
   4.160              on GroupKeys
   4.161                  do saveGroupKeys;