... sync
authorVolker Birk <vb@pep-project.org>
Wed, 01 May 2019 17:24:51 +0200
branchsync
changeset 35947f2ef2823948
parent 3593 5085ee740dda
child 3595 d491c5d5ef2a
...
sync/cond_act_sync.yml2
sync/gen_message_func.ysl2
sync/gen_statemachine.ysl2
sync/sync.fsm
     1.1 --- a/sync/cond_act_sync.yml2	Tue Apr 30 22:58:32 2019 +0200
     1.2 +++ b/sync/cond_act_sync.yml2	Wed May 01 17:24:51 2019 +0200
     1.3 @@ -153,6 +153,8 @@
     1.4  ||
     1.5      memset(session->sync_state.keysync.negotiation.buf, 0,
     1.6              session->sync_state.keysync.negotiation.size);
     1.7 +    memset(session->own_sync_state.negotiation.buf, 0,
     1.8 +            session->own_sync_state.negotiation.size);
     1.9  ||
    1.10  
    1.11  action storeTransaction {
    1.12 @@ -274,9 +276,9 @@
    1.13      if (status)
    1.14          return status;
    1.15  
    1.16 -    if (session->sync_state.common.own_keys)
    1.17 -        free_stringlist(session->sync_state.common.own_keys);
    1.18 -    session->sync_state.common.own_keys = own_keys;
    1.19 +    if (session->own_sync_state.own_keys)
    1.20 +        free_stringlist(session->own_sync_state.own_keys);
    1.21 +    session->own_sync_state.own_keys = own_keys;
    1.22  
    1.23      identity_list *il;
    1.24      status = _own_identities_retrieve(session, &il, PEP_idf_not_for_sync);
    1.25 @@ -309,7 +311,7 @@
    1.26      PEP_STATUS status = PEP_STATUS_OK;
    1.27  
    1.28      // set flag for current keys
    1.29 -    for (identity_list *il = session->sync_state.common.own_identities; il && il->ident ; il = il->next) {
    1.30 +    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
    1.31          if (!(il->ident->flags && PEP_idf_not_for_sync)) {
    1.32              status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
    1.33              if (status)
    1.34 @@ -323,7 +325,7 @@
    1.35      PEP_STATUS status = PEP_STATUS_OK;
    1.36  
    1.37      // set flag for current keys
    1.38 -    for (identity_list *il = session->sync_state.common.own_identities; il && il->ident ; il = il->next) {
    1.39 +    for (identity_list *il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
    1.40          if (!(il->ident->flags && PEP_idf_not_for_sync)) {
    1.41              status = set_identity_flags(session, il->ident, PEP_idf_devicegroup);
    1.42              if (status)
    1.43 @@ -335,7 +337,7 @@
    1.44      if (!il)
    1.45          return PEP_OUT_OF_MEMORY;
    1.46  
    1.47 -    for (il = session->sync_state.common.own_identities; il && il->ident ; il = il->next) {
    1.48 +    for (il = session->own_sync_state.own_identities; il && il->ident ; il = il->next) {
    1.49          // replace partner's user_id with own user_id
    1.50          free(il->ident->user_id);
    1.51          il->ident->user_id = strdup(session->sync_state.common.from->user_id);
     2.1 --- a/sync/gen_message_func.ysl2	Tue Apr 30 22:58:32 2019 +0200
     2.2 +++ b/sync/gen_message_func.ysl2	Wed May 01 17:24:51 2019 +0200
     2.3 @@ -39,19 +39,23 @@
     2.4  // state
     2.5  
     2.6  struct «@name»_state_s {
     2.7 +    // common buffer for all types of «@name» messages
     2.8 +
     2.9      struct common_state_s {
    2.10 +        // transport data
    2.11          pEp_identity *from;
    2.12 -        stringlist_t *own_keys;
    2.13 -        identity_list *own_identities;
    2.14 -
    2.15 -        // transport data
    2.16          char *signature_fpr;
    2.17      } common;
    2.18 -
    2.19      `` apply "fsm", mode=state
    2.20  };
    2.21  
    2.22 +// own state
    2.23 +
    2.24  struct own_«@name»_state_s {
    2.25 +    stringlist_t *own_keys;
    2.26 +    identity_list *own_identities;
    2.27 +
    2.28 +    `` if "func:distinctName(fsm/message/field[@type='TID'])" |> // active TIDs
    2.29      `` for "func:distinctName(fsm/message/field[@type='TID'])" |> «func:ctype()» «@name»;
    2.30  
    2.31      // transport data
    2.32 @@ -78,6 +82,9 @@
    2.33  
    2.34  template "fsm", mode=state
    2.35  ||
    2.36 +
    2.37 +// buffer for «@name» messages
    2.38 +
    2.39  struct _«@name»_state_s {
    2.40      int state;
    2.41  
    2.42 @@ -105,8 +112,8 @@
    2.43  
    2.44      free_identity(session->«yml:lcase(@name)»_state.common.from);
    2.45      free(session->«yml:lcase(@name)»_state.common.signature_fpr);
    2.46 -    free_stringlist(session->«yml:lcase(@name)»_state.common.own_keys);
    2.47 -    free_identity_list(session->«yml:lcase(@name)»_state.common.own_identities);
    2.48 +    free_stringlist(session->own_«yml:lcase(@name)»_state.own_keys);
    2.49 +    free_identity_list(session->own_«yml:lcase(@name)»_state.own_identities);
    2.50  
    2.51  ||
    2.52  for "fsm"
     3.1 --- a/sync/gen_statemachine.ysl2	Tue Apr 30 22:58:32 2019 +0200
     3.2 +++ b/sync/gen_statemachine.ysl2	Wed May 01 17:24:51 2019 +0200
     3.3 @@ -40,7 +40,6 @@
     3.4              pEp_identity *from;
     3.5              char *signature_fpr;
     3.6  
     3.7 -            // identities to sync
     3.8              identity_list *own_identities;
     3.9          } «@name»_event_t;
    3.10  
    3.11 @@ -418,6 +417,8 @@
    3.12                  identity_list *channels = NULL;
    3.13                  char *key_data = NULL;
    3.14                  size_t key_data_size = 0;
    3.15 +                stringlist_t *extra = NULL;
    3.16 +                bool transaction;
    3.17  
    3.18                  status = update_«@name»_message(session, msg);
    3.19                  if (status)
    3.20 @@ -498,8 +499,6 @@
    3.21                      }
    3.22                      memcpy(_data, data, size);
    3.23  
    3.24 -                    stringlist_t *extra = NULL;
    3.25 -
    3.26                      switch (message_type) {
    3.27                      `` for "fsm/message[@security='unencrypted']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.28                              status = base_prepare_message(
    3.29 @@ -519,22 +518,76 @@
    3.30                              m = _m;
    3.31                              break;
    3.32  
    3.33 -                    `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.34 -                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr &&
    3.35 -                                session->«yml:lcase(@name)»_state.common.from &&
    3.36 -                                session->«yml:lcase(@name)»_state.common.from->user_id);
    3.37 -                            if (!(session->«yml:lcase(@name)»_state.common.signature_fpr &&
    3.38 -                                    session->«yml:lcase(@name)»_state.common.from &&
    3.39 -                                    session->«yml:lcase(@name)»_state.common.from->user_id))
    3.40 -                            {
    3.41 +                    `` for "fsm/message[@security='untrusted']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.42 +                            // add fpr of key of comm partner
    3.43 +
    3.44 +                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.45 +                            if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
    3.46                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.47                                  goto the_end;
    3.48                              }
    3.49 +
    3.50 +                            extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
    3.51 +                            if (!extra) {
    3.52 +                                status = PEP_OUT_OF_MEMORY;
    3.53 +                                goto the_end;
    3.54 +                            }
    3.55 +
    3.56 +                            status = base_prepare_message(
    3.57 +                                    session,
    3.58 +                                    li->ident,
    3.59 +                                    li->ident,
    3.60 +                                    _data,
    3.61 +                                    size,
    3.62 +                                    NULL,
    3.63 +                                    &_m
    3.64 +                                );
    3.65 +                            if (status) {
    3.66 +                                free(_data);
    3.67 +                                goto the_end;
    3.68 +                            }
    3.69 +
    3.70 +                            status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
    3.71 +                            if (status) {
    3.72 +                                status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
    3.73 +                                goto the_end;
    3.74 +                            }
    3.75 +                            free_message(_m);
    3.76 +                            break;
    3.77 +
    3.78 +                    `` for "fsm/message[@security='attach_own_keys']" |>>> case «../@name»_PR_«yml:mixedCase(@name)»:
    3.79 +                            // check if this is the key of a former negotiation
    3.80 +
    3.81 +                            transaction = false;
    3.82 +                            for (int i=0; i < session->own_«yml:lcase(@name)»_state.negotiation.size; i++) {
    3.83 +                                if (session->own_«yml:lcase(@name)»_state.negotiation.buf[i]) {
    3.84 +                                    transaction = true;
    3.85 +                                    break;
    3.86 +                                }
    3.87 +                            }
    3.88 +    
    3.89 +                            // if it is a former negotiation check if the key
    3.90 +                            // is fully trusted and the sender key of this
    3.91 +                            // transaction; if so add the sender key to extra
    3.92 +                            // keys allowing this new partner to read the
    3.93 +                            // secret keys
    3.94 +
    3.95 +                            if (transaction) {
    3.96 +                                assert(session->own_«yml:lcase(@name)»_state.signature_fpr &&
    3.97 +                                    session->«yml:lcase(@name)»_state.common.from &&
    3.98 +                                    session->«yml:lcase(@name)»_state.common.from->user_id);
    3.99 +                                if (!(session->own_«yml:lcase(@name)»_state.signature_fpr &&
   3.100 +                                        session->«yml:lcase(@name)»_state.common.from &&
   3.101 +                                        session->«yml:lcase(@name)»_state.common.from->user_id))
   3.102 +                                {
   3.103 +                                    status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   3.104 +                                    goto the_end;
   3.105 +                                }
   3.106                              
   3.107 -                            // double check if we fully trust this comm partner
   3.108 -                            {
   3.109 +                                // test if this is a green channel
   3.110 +
   3.111                                  pEp_identity *ident = new_identity(NULL,
   3.112 -                                        session->«yml:lcase(@name)»_state.common.signature_fpr,
   3.113 +                                        session->own_«yml:lcase(@name)»_state.signature_fpr,
   3.114                                          session->«yml:lcase(@name)»_state.common.from->user_id,
   3.115                                          NULL
   3.116                                      );
   3.117 @@ -554,6 +607,29 @@
   3.118                                      goto the_end;
   3.119                                  }
   3.120                                  free_identity(ident);
   3.121 +
   3.122 +                                // test if we accepted this as own key already
   3.123 +
   3.124 +                                bool is_own_key = false;
   3.125 +                                status = own_key_is_listed(session,
   3.126 +                                        session->own_«yml:lcase(@name)»_state.signature_fpr,
   3.127 +                                        &is_own_key);
   3.128 +                                assert(!status);
   3.129 +                                if (status)
   3.130 +                                    goto the_end;
   3.131 +                                assert(is_own_key);
   3.132 +                                if (!is_own_key) {
   3.133 +                                    status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   3.134 +                                    goto the_end;
   3.135 +                                }
   3.136 +
   3.137 +                                // if so add key of comm partner to extra keys
   3.138 +
   3.139 +                                extra = new_stringlist(session->own_«yml:lcase(@name)»_state.signature_fpr);
   3.140 +                                if (!extra) {
   3.141 +                                    status = PEP_OUT_OF_MEMORY;
   3.142 +                                    goto the_end;
   3.143 +                                }
   3.144                              }
   3.145                              
   3.146                              status = base_prepare_message(
   3.147 @@ -582,7 +658,7 @@
   3.148                              }
   3.149                              key_data_size = 1;
   3.150  
   3.151 -                            for (stringlist_t *sl = session->«yml:lcase(@name)»_state.common.own_keys;
   3.152 +                            for (stringlist_t *sl = session->own_«yml:lcase(@name)»_state.own_keys;
   3.153                                      sl && sl->value ; sl = sl->next)
   3.154                              {
   3.155                                  char *_key_data = NULL;
   3.156 @@ -645,16 +721,7 @@
   3.157                              }
   3.158                              key_data = NULL;
   3.159  
   3.160 -                            // add fpr of key of comm partner
   3.161 -
   3.162 -                            extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
   3.163 -                            if (extra) {
   3.164 -                                status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
   3.165 -                                free_stringlist(extra);
   3.166 -                            }
   3.167 -                            else {
   3.168 -                                status = PEP_OUT_OF_MEMORY;
   3.169 -                            }
   3.170 +                            status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
   3.171                              if (status) {
   3.172                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   3.173                                  goto the_end;
   3.174 @@ -662,7 +729,7 @@
   3.175                              free_message(_m);
   3.176                              break;
   3.177  
   3.178 -                        default:
   3.179 +                        default: // security=trusted only
   3.180                              status = base_prepare_message(
   3.181                                      session,
   3.182                                      li->ident,
   3.183 @@ -677,20 +744,7 @@
   3.184                                  goto the_end;
   3.185                              }
   3.186  
   3.187 -                            assert(session->«yml:lcase(@name)»_state.common.signature_fpr);
   3.188 -                            if (!session->«yml:lcase(@name)»_state.common.signature_fpr) {
   3.189 -                                status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   3.190 -                                goto the_end;
   3.191 -                            }
   3.192 -
   3.193 -                            stringlist_t *extra = new_stringlist(session->«yml:lcase(@name)»_state.common.signature_fpr);
   3.194 -                            if (extra) {
   3.195 -                                status = encrypt_message(session, _m, extra, &m, PEP_enc_PEP, 0);
   3.196 -                                free_stringlist(extra);
   3.197 -                            }
   3.198 -                            else {
   3.199 -                                status = PEP_OUT_OF_MEMORY;
   3.200 -                            }
   3.201 +                            status = encrypt_message(session, _m, NULL, &m, PEP_enc_PEP, 0);
   3.202                              if (status) {
   3.203                                  status = PEP_«yml:ucase(@name)»_CANNOT_ENCRYPT;
   3.204                                  goto the_end;
   3.205 @@ -703,6 +757,7 @@
   3.206                  }
   3.207  
   3.208              the_end:
   3.209 +                free_stringlist(extra);
   3.210                  free_identity_list(channels);
   3.211                  free_message(m);
   3.212                  free(data);
   3.213 @@ -762,8 +817,8 @@
   3.214                  // update own identities
   3.215  
   3.216                  if (ev->own_identities && ev->own_identities->ident) {
   3.217 -                    free_identity_list(session->«yml:lcase(@name)»_state.common.own_identities);
   3.218 -                    session->«yml:lcase(@name)»_state.common.own_identities = ev->own_identities;
   3.219 +                    free_identity_list(session->own_«yml:lcase(@name)»_state.own_identities);
   3.220 +                    session->own_«yml:lcase(@name)»_state.own_identities = ev->own_identities;
   3.221                      ev->own_identities = NULL;
   3.222                  }
   3.223  
   3.224 @@ -1134,7 +1189,7 @@
   3.225                  `` apply "event", 2, mode=fsm
   3.226                  default:
   3.227                      // ignore events not handled here
   3.228 -                    «../@name»_SERVICE_LOG("ignoring event", KeySync_event_name(event));
   3.229 +                    «../@name»_SERVICE_LOG("ignoring event", «../@name»_event_name(event));
   3.230                      return invalid_event;
   3.231              }
   3.232              break;
     4.1 --- a/sync/sync.fsm	Tue Apr 30 22:58:32 2019 +0200
     4.2 +++ b/sync/sync.fsm	Wed May 01 17:24:51 2019 +0200
     4.3 @@ -535,7 +535,7 @@
     4.4              field Hash key;
     4.5          }
     4.6  
     4.7 -        // security=attach_own_keys implies security=trusted
     4.8 +        // trust in future
     4.9          message GroupKeys 12, security=attach_own_keys {
    4.10              field IdentityList ownIdentities;
    4.11          }