signing of beacons sync
authorVolker Birk <vb@pep.foundation>
Tue, 20 Nov 2018 17:18:46 +0100
branchsync
changeset 314381c80e27cbf7
parent 3139 d9b3c218af20
child 3144 334a6c3faacd
signing of beacons
src/baseprotocol.c
src/baseprotocol.h
src/message_api.c
sync/gen_statemachine.ysl2
     1.1 --- a/src/baseprotocol.c	Tue Nov 20 15:02:43 2018 +0100
     1.2 +++ b/src/baseprotocol.c	Tue Nov 20 17:18:46 2018 +0100
     1.3 @@ -5,12 +5,15 @@
     1.4  #include "message_api.h"
     1.5  
     1.6  PEP_STATUS base_decorate_message(
     1.7 +        PEP_SESSION session,
     1.8          message *msg,
     1.9          char *payload,
    1.10          size_t size,
    1.11          char *fpr
    1.12      )
    1.13  {
    1.14 +    PEP_STATUS status = PEP_STATUS_OK;
    1.15 +
    1.16      assert(msg);
    1.17      assert(payload);
    1.18      assert(size);
    1.19 @@ -24,17 +27,31 @@
    1.20          goto enomem;
    1.21  
    1.22      if (fpr) {
    1.23 -        // add signature
    1.24 +        char *sign;
    1.25 +        size_t sign_size;
    1.26 +        status = sign_only(session,  payload, size, fpr, &sign, &sign_size);
    1.27 +        if (status)
    1.28 +            goto error;
    1.29 +
    1.30 +        assert(sign && sign_size);
    1.31 +
    1.32 +        bl = bloblist_add(bl, sign, sign_size,
    1.33 +                "application/pEp.sign", "ignore_this_attachment.pEp");
    1.34 +        if (!bl)
    1.35 +            goto enomem;
    1.36      }
    1.37  
    1.38 -    msg->attachments = bl;
    1.39      return PEP_STATUS_OK;
    1.40  
    1.41  enomem:
    1.42 -    return PEP_OUT_OF_MEMORY;
    1.43 +    status = PEP_OUT_OF_MEMORY;
    1.44 +
    1.45 +error:
    1.46 +    return status;
    1.47  }
    1.48  
    1.49  PEP_STATUS base_prepare_message(
    1.50 +        PEP_SESSION session,
    1.51          const pEp_identity *me,
    1.52          const pEp_identity *partner,
    1.53          char *payload,
    1.54 @@ -81,7 +98,7 @@
    1.55      if (!msg->longmsg)
    1.56          goto enomem;
    1.57  
    1.58 -    status = base_decorate_message(msg, payload, size, fpr);
    1.59 +    status = base_decorate_message(session, msg, payload, size, fpr);
    1.60      if (status == PEP_STATUS_OK)
    1.61          *result = msg;
    1.62      return status;
    1.63 @@ -91,25 +108,79 @@
    1.64      return PEP_OUT_OF_MEMORY;
    1.65  }
    1.66  
    1.67 -PEP_STATUS base_extract_message(message *msg, size_t *size, const char **payload)
    1.68 +PEP_STATUS base_extract_message(
    1.69 +        PEP_SESSION session,
    1.70 +        message *msg,
    1.71 +        size_t *size,
    1.72 +        const char **payload,
    1.73 +        char **fpr
    1.74 +    )
    1.75  {
    1.76      PEP_STATUS status = PEP_STATUS_OK;
    1.77  
    1.78 -    assert(msg && size && payload);
    1.79 -    if (!(msg && size && payload))
    1.80 +    assert(session && msg && size && payload && fpr);
    1.81 +    if (!(session && msg && size && payload && fpr))
    1.82          return PEP_ILLEGAL_VALUE;
    1.83  
    1.84      *size = 0;
    1.85      *payload = NULL;
    1.86  
    1.87 +    const char *_payload = NULL;
    1.88 +    size_t _payload_size = 0;
    1.89 +    const char *_sign = NULL;
    1.90 +    size_t _sign_size = 0;
    1.91 +    stringlist_t *keylist = NULL;
    1.92 +
    1.93      for (bloblist_t *bl = msg->attachments; bl ; bl = bl->next) {
    1.94          if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sync") == 0) {
    1.95 -            *size = bl->size;
    1.96 -            *payload = bl->value;
    1.97 -            break;
    1.98 +            if (!_payload) {
    1.99 +                _payload = bl->value;
   1.100 +                _payload_size = bl->size;
   1.101 +            }
   1.102 +            else {
   1.103 +                status = PEP_DECRYPT_WRONG_FORMAT;
   1.104 +                goto the_end;
   1.105 +            }
   1.106 +        }
   1.107 +        else if (bl->mime_type && strcasecmp(bl->mime_type, "application/pEp.sign") == 0) {
   1.108 +            if (!_sign) {
   1.109 +                _sign = bl->value;
   1.110 +                _sign_size = bl->size;
   1.111 +            }
   1.112 +            else {
   1.113 +                status = PEP_DECRYPT_WRONG_FORMAT;
   1.114 +                goto the_end;
   1.115 +            }
   1.116          }
   1.117      }
   1.118 +    
   1.119 +    if (!(_payload && _payload_size))
   1.120 +        goto the_end;
   1.121  
   1.122 +    if (_sign) {
   1.123 +        status = verify_text(session, _payload, _payload_size, _sign, _sign_size, &keylist);
   1.124 +        if (status != PEP_VERIFIED || !keylist || !keylist->value) {
   1.125 +            // signature invalid or does not match; ignore sync message
   1.126 +            status = PEP_STATUS_OK;
   1.127 +            goto the_end;
   1.128 +        }
   1.129 +
   1.130 +        char *_fpr = strdup(keylist->value);
   1.131 +        assert(_fpr);
   1.132 +        if (!_fpr) {
   1.133 +            status = PEP_OUT_OF_MEMORY;
   1.134 +            goto the_end;
   1.135 +        }
   1.136 +
   1.137 +        *fpr = _fpr;
   1.138 +    }
   1.139 +
   1.140 +    *size = _payload_size;
   1.141 +    *payload = _payload;
   1.142 +    status = PEP_STATUS_OK;
   1.143 +
   1.144 +the_end:
   1.145 +    free_stringlist(keylist);
   1.146      return status;
   1.147  }
   1.148  
     2.1 --- a/src/baseprotocol.h	Tue Nov 20 15:02:43 2018 +0100
     2.2 +++ b/src/baseprotocol.h	Tue Nov 20 17:18:46 2018 +0100
     2.3 @@ -13,6 +13,7 @@
     2.4  // base_decorate_message() - decorate a message with payload
     2.5  //
     2.6  //  parameters:
     2.7 +//      session (in)    session handle
     2.8  //      msg (inout)     message to decorate
     2.9  //      payload (in)    payload to send
    2.10  //      size (in)       size of payload
    2.11 @@ -26,6 +27,7 @@
    2.12  //      the ownership of the msg remains with the caller
    2.13  
    2.14  PEP_STATUS base_decorate_message(
    2.15 +        PEP_SESSION session,
    2.16          message *msg,
    2.17          char *payload,
    2.18          size_t size,
    2.19 @@ -36,6 +38,7 @@
    2.20  // base_prepare_message() - prepare a sync message with payload
    2.21  //
    2.22  //  parameters:
    2.23 +//      session (in)    session handle
    2.24  //      me (in)         identity to use for the sender
    2.25  //      partner (in)    identity to use for the receiver
    2.26  //      payload (in)    payload to send
    2.27 @@ -51,6 +54,7 @@
    2.28  //      the ownership of the result goes to the caller
    2.29  
    2.30  PEP_STATUS base_prepare_message(
    2.31 +        PEP_SESSION session,
    2.32          const pEp_identity *me,
    2.33          const pEp_identity *partner,
    2.34          char *payload,
    2.35 @@ -63,9 +67,12 @@
    2.36  // base_extract_message() - extract a sync message from a pEp message
    2.37  //
    2.38  //  parameters:
    2.39 +//      session (in)    session handle
    2.40  //      msg (in)        message to analyze
    2.41  //      size (out)      size of extracted payload or 0 if not found
    2.42  //      payload (out)   extraced payload
    2.43 +//      fpr (out)       if message was correctly signed then fpr of signature's
    2.44 +//                      key, otherwise NULL
    2.45  //
    2.46  //  returns:
    2.47  //      PEP_STATUS_OK and payload == NULL if no sync message
    2.48 @@ -74,8 +81,15 @@
    2.49  //
    2.50  //  caveat:
    2.51  //      payload may point to msg attachment, the ownership does not change
    2.52 +//      if fpr != NULL the ownership goes to the caller
    2.53  
    2.54 -PEP_STATUS base_extract_message(message *msg, size_t *size, const char **payload);
    2.55 +PEP_STATUS base_extract_message(
    2.56 +        PEP_SESSION session,
    2.57 +        message *msg,
    2.58 +        size_t *size,
    2.59 +        const char **payload,
    2.60 +        char **fpr
    2.61 +    );
    2.62  
    2.63  
    2.64  #ifdef __cplusplus
     3.1 --- a/src/message_api.c	Tue Nov 20 15:02:43 2018 +0100
     3.2 +++ b/src/message_api.c	Tue Nov 20 17:18:46 2018 +0100
     3.3 @@ -3749,6 +3749,7 @@
     3.4      if (!(session && src && dst && keylist && rating && flags))
     3.5          return PEP_ILLEGAL_VALUE;
     3.6  
     3.7 +    *keylist = NULL;
     3.8      PEP_STATUS status = _decrypt_message(session, src, dst, keylist, rating, flags, NULL);
     3.9  
    3.10      message *msg = *dst ? *dst : src;
    3.11 @@ -3756,9 +3757,12 @@
    3.12      if (session->inject_sync_event && msg) {
    3.13          size_t size;
    3.14          const char *data;
    3.15 -        status = base_extract_message(msg, &size, &data);
    3.16 -        if (size && data)
    3.17 -            signal_Sync_message(session, *rating, data, size);
    3.18 +        char *sync_fpr = NULL;
    3.19 +        status = base_extract_message(session, msg, &size, &data, &sync_fpr);
    3.20 +        const char *fpr = (*keylist && (*keylist)->value) ? (*keylist)->value : sync_fpr;
    3.21 +        if (size && data && fpr)
    3.22 +            signal_Sync_message(session, *rating, data, size, fpr);
    3.23 +        free(sync_fpr);
    3.24      }
    3.25  
    3.26      return status;
     4.1 --- a/sync/gen_statemachine.ysl2	Tue Nov 20 15:02:43 2018 +0100
     4.2 +++ b/sync/gen_statemachine.ysl2	Tue Nov 20 17:18:46 2018 +0100
     4.3 @@ -197,7 +197,8 @@
     4.4                      PEP_SESSION session, 
     4.5                      PEP_rating rating,
     4.6                      const char *data,
     4.7 -                    size_t size
     4.8 +                    size_t size,
     4.9 +                    const char *fpr
    4.10                  );
    4.11  
    4.12              #ifdef __cplusplus
    4.13 @@ -310,7 +311,8 @@
    4.14                      PEP_SESSION session, 
    4.15                      PEP_rating rating,
    4.16                      const char *data,
    4.17 -                    size_t size
    4.18 +                    size_t size,
    4.19 +                    const char *fpr
    4.20                  )
    4.21              {
    4.22                  assert(session && data && size);
    4.23 @@ -337,6 +339,15 @@
    4.24                          goto the_end;
    4.25                  }
    4.26  
    4.27 +                if (session->«yml:lcase(@name)»_state.common.from->fpr)
    4.28 +                    free(session->«yml:lcase(@name)»_state.common.from->fpr);
    4.29 +                session->«yml:lcase(@name)»_state.common.from->fpr = strdup(fpr);
    4.30 +                assert(session->«yml:lcase(@name)»_state.common.from->fpr);
    4.31 +                if (!session->«yml:lcase(@name)»_state.common.from->fpr) {
    4.32 +                    status = PEP_OUT_OF_MEMORY;
    4.33 +                    goto the_end;
    4.34 +                }
    4.35 +
    4.36                  ev = new_«@name»_event(fsm, event, msg);
    4.37                  if (!ev) {
    4.38                      status = PEP_OUT_OF_MEMORY;
    4.39 @@ -349,6 +360,7 @@
    4.40                      status = PEP_STATEMACHINE_ERROR;
    4.41                      goto the_end;
    4.42                  }
    4.43 +
    4.44                  return PEP_STATUS_OK;
    4.45  
    4.46              the_end:
    4.47 @@ -455,6 +467,7 @@
    4.48                      switch (message_type) {
    4.49                      `` for "fsm/message[@security='unencrypted']" |>>> case «../@name»__payload_PR_«yml:mixedCase(@name)»:
    4.50                              status = base_prepare_message(
    4.51 +                                    session,
    4.52                                      li->ident,
    4.53                                      li->ident,
    4.54                                      _data,
    4.55 @@ -472,6 +485,7 @@
    4.56  
    4.57                          default:
    4.58                              status = base_prepare_message(
    4.59 +                                    session,
    4.60                                      li->ident,
    4.61                                      li->ident,
    4.62                                      _data,