otr4j / otr4j-issues

1 stars 0 forks source link

How should we expose the Type 8 TLV? #8

Closed cobratbq closed 4 years ago

cobratbq commented 9 years ago

First of all, this is related to PR https://github.com/otr4j/otr4j/pull/16 . (And we need to fix https://github.com/otr4j/otr4j/issues/11 in order for this to work properly.)

So, @eighthave suggests to make TLVs strictly an internal mechanism. I agree with that, however, in the case of the extra symmetric key (https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html section "Extra symmetric key"), we are more or less required to expose the TLV.

The section only describes how the key itself is computed, but there is a TLV, "Type 8", which signals to the client that the remote party "calls upon" using the extra symmetric key. Additionally, there is room for data in the TLV packet and there is no description on how the data is supposed to be filled, if at all.

My suggestion is to expose the raw []byte data from the TLV to the client, since:

  1. the protocol does not specify explicitly that we should not use it,
  2. we cannot predict how this data will be used,
  3. I can imagine using the data to store an identifier to explain which out-of-band channel we should symm. encrypt. (For example, we ship a message pointing to a separate video stream and we attach Type 8 TLV to indicate that we should decrypt this video stream using the extra symmetric key.)
  4. since the usage is "out-of-band", otr4j cannot be called upon to handle this content. (Or do we want to make the client redirect traffic via the otr4j session instance? ... it sounds like a bad idea, IMO.)

So AFAICT we can't do much more than expose the raw TLV data. We could have a method saying 'isSymmetricKeyUsed()' which returns a []byte if TLV8 was attached, or null if not.

eighthave commented 9 years ago

I see it quite simliarly as you describe, but maybe this TLV8 stuff is too raw to actually be implemented in an API? If there isn't even a test implementation in the canonical libotr, then I don't think we should sweat too much over implementing it. But what is specified is quite simple, so we can start just by exposing that:

Type 8: Extra symmetric key If you wish to use the extra symmetric key, compute it yourself as outlined in the section "Extra symmetric key", below. Then send this type 8 TLV to your buddy to indicate that you'd like to use the extra symmetric key for something. The value of the TLV begins with a 4-byte indication of what this symmetric key will be used for (file transfer, voice encryption, etc.). After that, the contents are use-specific (which file, etc.). There are no currently defined uses. Note that the value of the key itself is not placed into the TLV; your buddy will compute it on his/her own. https://otr.cypherpunks.ca/Protocol-v3-4.0.0.html

The way I understand TLV8 is there are two parts: the process for calculating the Extra Symmetric Key, and the TLV8 message to signal the other side to do something with the Extra Symmetric Key. I don't think that the data in the TLV8 field of the incoming message actually has anything to do with the Extra Symmetric Key, it is just a signal to use it. So I think your method of Session.getExtraSymmetricKey() is a perfect API for getting the Extra Symmetric Key (05f9b66e6df12d1df5fa75473286769cf8b69730). As far as I understand it, that can happen anytime a session is active, and is not actually tied to the sending or receiving of TLV8 messages.

So then the open question is just getting the data from the TLV8 message. Since OtrEngineHost is the main receiving interface in otr4j, we should add a method there that represents TLV8. I think the "use-specific part" should be a byte[] like you said. The first argument should just be the parsed out "4-byte indication of what this symmetric key will be used for". So a method like:

public abstract void useExtraSymmetricKeyReceived(SessionID sessionID,
            long useType, byte[] data) throws OtrException;

I specified long for useType so that the 4-byte value can be represented using positive integers, but maybe it makes sense to use int. The other question I had was whether it should give a Session instance rather than a SessionID. So far, the OtrEngineHost always receives SessionID, so it is more consistent to use SessionID. But since receiving a TLV8 out-of-band transfer will require a Session.getExtraSymmetricKey(), maybe it makes sense here.

eighthave commented 9 years ago

I'm starting to think that your original structure of using a new class to represent the parsed message from OTR makes sense, like you outline in otr4j-temp/otr4j#29 and 05f9b66. But it can't be named Message since there are so many classes with names like that, especially when you look at XMPP libs. I'm going to work today on integrating the OTRDATA RESPONSE/REQUEST stuff today, and see if I find any clarity.

cobratbq commented 9 years ago

Okay, so basically there's a few things to take care of:

  1. Some "Message" class (not actually called Message) which contains content + secure-state + ... so everything about the message is combined in the return value.
  2. Exposing the extra symmetric key via the Session object, as already proposed.
  3. Finding some method for supporting Type 8 TLV that is at least somewhat consistent and agreeable. There are no real applications to date (I think) so there is no rush in implementing this part and no clear path of implementation.

I'll keep this issue open until 1 and 2 are fixed. And we'll need to see what to do with 3 in time. As for now, I consider 3 unimportant.

eighthave commented 9 years ago

sounds good to me. I think of the new class in 1. as "message plus metadata". I think it'll be quite useful to have the metadata easily available so that it can be displayed. For example, a chat log view can use the metadata to visually display which messages where encrypted and which not.

Perhaps it also makes sense to think of this "message plus metadata" class as a class that apps can subclass to use as their internal representation of each message.

eighthave commented 9 years ago

FYI, I filed an issue about an "experimental range" for TLV8: https://bugs.otr.im/issues/86

cobratbq commented 5 years ago

This is still an ongoing discussion (at least for OTRv4) and will be revisited later.