[OTR-dev] Last-minute change to libotr 4 API

Ian Goldberg ian at cypherpunks.ca
Sun Aug 26 11:52:19 EDT 2012


On Sun, Aug 26, 2012 at 09:46:10AM -0400, Ian Goldberg wrote:
> On Sat, Aug 25, 2012 at 09:03:56PM -0700, Howard Chu wrote:
> > Since there are no other uses for this yet, it might be better to make this a
> > oneshot function. And change the signature of otrl_poll() to also return a
> > polltime. If it returns 0, then no further polling is desired, otherwise the
> > return value is the interval till the next desired poll.
> 
> I thought of that, but it doesn't quite work.  Or rather, otrl_poll
> could *never* return 0, since a new OTR conversation may start at some
> later time, and would need to be scheduled to be cleaned.  You'd have to
> have *every* otrl_* call by the application have the ability to create
> and destroy timers.  So another way to do it would be to have new
> callback functions in OtrlMessageUiOps to create and destroy timers.
> But that also seems ugly to me, and requires more infrastructure from
> the calling app than just "call this function every so often".

OK, I think I have a compromise proposal that only requires the simplest
timer support from the application, while at the same time does not set
off timers all the time, when they're actually needed only rarely.

The new proposal is to add a callback function to OtrlMessageUiOps:

    /* 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);

Then libotr will call that callback to turn on and off the timer, as
needed.

I'm actually pretty happy with this version.  You could imagine a much
more complicated callback that was itself passed a callback for the
application to call (instead of the hardcoded otrl_message_poll),
requiring the application to support multiple simultaneous timers, etc.,
but this is a simple and clean API that only requires the application to
support "turn on a single periodic timer with the given approximate
period" and "turn off that timer".

More discussion?

Thanks,

   - Ian



More information about the OTR-dev mailing list