otrv4 / libotr-ng

A new implementation of OTR with support for version 4. This is a mirror of https://bugs.otr.im/otrv4/libotr-ng
Other
43 stars 9 forks source link

Ideas from libotr... should we have them? #183

Closed claucece closed 3 years ago

claucece commented 5 years ago

There is some functionality in libotr that we might want to have:

  1. Convert Operations

There is a callback that is made immediately before a message is encrypted and immediately after a message is decrypted. This callback can tweak the plaintext message as needed. For example, this could allow an application to convert formatting on a message if this would normally be done on the plaintext by some other entity while the message is in transit.

Do we think is useful?

  1. Add prefix to resent messages

Libotr has:

/* Return a string that will be prefixed to any resent message. If this

These operations give the option of chosing an alternative to the English string "[resent]", when a message is resent.

  1. Timer

Libotr has:

/* When timer_control is called, turn off any existing periodic
 * timer.
 * 
 * Additionally, if interval > 0, set a new periodic timer
 * to go off every interval seconds.  When that timer fires, you
 * must call otrl_message_poll(userstate, uiops, uiopdata); from the
 * main libotr thread.
 * 
 * The timing does not have to be exact; this timer is used to
 * provide forward secrecy by cleaning up stale private state that
 * may otherwise stick around in memory.  Note that the
 * timer_control callback may be invoked from otrl_message_poll
 * itself, possibly to indicate that interval == 0 (that is, that
 * there's no more periodic work to be done at this time).
 * 
 * If you set this callback to NULL, then you must ensure that your
 * application calls otrl_message_poll(userstate, uiops, uiopdata);
 * from the main libotr thread every definterval seconds (where
 * definterval can be obtained by calling
 * definterval = otrl_message_poll_get_default_interval(userstate);
 * right after creating the userstate).  The advantage of
 * implementing the timer_control callback is that the timer can be
 * turned on by libotr only when it's needed.
 * 
 * It is not a problem (except for a minor performance hit) to call
 * otrl_message_poll more often than requested, whether
 * timer_control is implemented or not.
 * 
 * If you fail to implement the timer_control callback, and also
 * fail to periodically call otrl_message_poll, then you open your
 * users to a possible forward secrecy violation: an attacker that
 * compromises the user's computer may be able to decrypt a handful
 * of long-past messages (the first messages of an OTR
 * conversation).
 */
void (*timer_control)(void *opdata, unsigned int interval);

In order to prevent a forward secrecy violation, applications using libotr now need to be able to call otrl_message_poll on occasion. The simplest thing to do is just to set up a local timer that calls that function every definterval = otrl_message_poll_get_default_interval(userstate) seconds. To avoid unnecessary overhead, however, the timer_control callback is available. If you set timer_control to non-NULL, it will be called with instructions to turn on or off the periodic timer, and to what interval.

We have something similar with the session expiration.. should we revisit its design?

  1. Asynchronous Private Key Generation

An application that wants to begin asynchronous key generation calls the following method in libotr:

/* Begin a private key generation that will potentially take place in
 * a background thread.  This routine must be called from the main
 * thread.  It will set *newkeyp, which you can pass to
 * otrl_privkey_generate_calculate in a background thread.  If it
 * returns gcry_error(GPG_ERR_EEXIST), then a privkey creation for
 * this accountname/protocol is already in progress, and *newkeyp will
 * be set to NULL. */
gcry_error_t otrl_privkey_generate_start(OtrlUserState us,
        const char *accountname, const char *protocol, void **newkeyp)

A background thread can call the following method with the structure that was passed into "newkeyp" above:

/* Do the private key generation calculation.  You may call this from a
 * background thread.  When it completes, call
 * otrl_privkey_generate_finish from the _main_ thread. */
gcry_error_t otrl_privkey_generate_calculate(void *newkey)

Upon completion the application would call:

/* Call this from the main thread only.  It will write the newly created
 * private key into the given file and store it in the OtrlUserState. */
gcry_error_t otrl_privkey_generate_finish(OtrlUserState us,
        void *newkey, const char *filename)

If the privkey generation was cancelled, the application should call:

/* Call this from the main thread only, in the event that the background
 * thread generating the key is cancelled.  The newkey is deallocated,
 * and must not be used further. */
void otrl_privkey_generate_cancelled(OtrlUserState us, void *newkey)

should we have something like this?

claucece commented 5 years ago

@olabini @DrWhax thoughts?

claucece commented 5 years ago

After talking about this, we decided to have:

  1. Convert Operations
  2. Add prefix to resent messages

We should discuss the 'timer' functionality in person.. want to do that next week @olabini ?

olabini commented 5 years ago

Both 1 and 2 are good to have - and #194 is now opened to discuss timers, so all good.

claucece commented 3 years ago

This was covered by #194, and the other ideas don't seem to apply anymore.