esl / jerboa

STUN/TURN encoder, decoder and client library in Elixir
https://www.erlang-solutions.com/products/mongooseim.html
Other
14 stars 6 forks source link

Implement an easy way to find out that the message integrity was verified #81

Closed arkgil closed 7 years ago

arkgil commented 7 years ago

There are issues with server side processing of decoded messages, especially of current design of how verifying message integrity works. Currently there are three cases of decoding messages with MI:

  1. STUN message doesn't have message integrity attribute - in this case decoding will always pass and there is no way to know if we actually verified it or not
  2. STUN message has message integrity attribute, but required values (username, realm and secret) aren't in the message or aren't provided in options list - in this case decoding will fail

    note: secret can only be provided in options list

  3. STUN message has message integrity; username, realm and secret are in the message or were provided in the options list but message integrity was invalid - again, decoding fails

    there are actually 4 cases, the last one is when message integrity is successfully verified

This all works well with client side code, because TURN client doesn't require the server to include message integrity - we just pass the secret every time, and if there is a message integrity, we try to verify it.

On the server side we would like to know if the message was verified after decoding it. Right now there is no way to know if decoded message was verified. My proposal it add :verified? field to Jerboa.Params struct.

In the first of mentioned situations, this field would be set to false, because there is nothing to verify - the request wasn't autenticated. In the second example the decoding should succeed, but the field will be set to false again. In the third case we could also let the decoding pass and set this flag to false.

/cc @rslota @mentels

rslota commented 7 years ago

The described method feels sufficient.

As long the message decoding always succeeds and there is a way of knowing about verification status afterwards, I can't see cases when this would be a problem on server side.

arkgil commented 7 years ago

Great. I'll take care of that.

rslota commented 7 years ago

There is actually one more thing. According to RFC:

If the message contains a MESSAGE-INTEGRITY attribute, but is
      missing the USERNAME, REALM, or NONCE attribute, the server MUST
      generate an error response with an error code of 400 (Bad
      Request).  This response SHOULD NOT include a USERNAME, NONCE,
      REALM, or MESSAGE-INTEGRITY attribute.

As you can see, it's important for server to know exactly what went wrong while decoding. In this case sever needs to know that there was indeed mesage-integrity included for this message in order to know that it needs to respond with 400 error code, not 401.

arkgil commented 7 years ago

How about adding :signed? field in the Params struct, which will be set to true if there was message integrity in the message. Relevant attribtues can be retrieved using Params.get_attr if necessary.

rslota commented 7 years ago

That would be great. I think :signed? and :verified? cover all cases.