[OTR-dev] Re: Re: Requirements for libotr4

Uli M a.sporto+bee at gmail.com
Mon Jun 23 16:03:34 EDT 2008


On Sat 21.06.08 10:52, Ian Goldberg wrote:
> See what happens when I post too early in the morning?  ;-)
> 
> On Sat, Jun 21, 2008 at 09:42:10AM -0400, Ian Goldberg wrote:
> >  /* Call this from the main thread only.  call_when_ready will be called
> >   * in the main thread. */
> >  gcry_error_t otrl_privkey_generate_start(OtrlUserState us,
> >      const char *accountname, const char *protocol,
> >      void (*call_when_ready)(void *newkey, void *data), void *data);
> > 
> >  /* You can call this from a different thread.  call_when_done will be
> >   * called in the different thread. */
> >  gcry_error_t otrl_privkey_generate_calculate(void *newkey,
> >      void (*call_when_done)(void *newkey, void *data), void *data);
> > 
> >  /* Call this from the main thread only. */
> >  gcry_error_t otrl_privkey_generate_finish(OtrlUserState us,
> >      void *newkey, FILE *fp);
> 
> With the specified division of threads, the callbacks are now
> unnecessary.
> 
>   /* Call this from the main thread only.  It will set *newkeyp, and
>    * then you can spawn a new thread if you wish, and call
>    * otrl_privkey_generate_calculate. */
>   gcry_error_t otrl_privkey_generate_start(OtrlUserState us,
>       const char *accountname, const char *protocol,
>       void **newkeyp);
>  
>   /* You can call this from a different thread.  When it completes, call
>    * otrl_privkey_generate_finish from the _main_ thread. */
>   gcry_error_t otrl_privkey_generate_calculate(void *newkey);
>  
>   /* Call this from the main thread only. */
>   gcry_error_t otrl_privkey_generate_finish(OtrlUserState us,
>       void *newkey, FILE *fp);
> 

That looks like what I had in mind. Although I didn't expect the extra
convenience of libotr checking for the presence of other key generations
;)

Currently in irssi-otr I'm checking myself whether a key generation is
already going on. With current libotr there can't be two generations at
the same time anyway since a second key generation process would overwrite
the result of the first.

> 
> But the questions about how to deal with keys autogenerated during the
> AKE are still important:
> 
> > But I've got a question for you, Uli:  key generation usually happens
> > when you get an incoming OTR Query or OTR Commit message.  If you spawn
> > off a thread to generate the key, how will you keep around the state you
> > need in order to remember to continue the AKE when you're done the key
> > generation?  In some languages, call-with-current-completion would
> > probably suffice, but otherwise it seems like a real pain.  In fact, I
> > think libotr has to know this, since message.c will be the one that has
> > to deal with this, since it calls ops->create_privkey.  If that routine
> > spawns a thread to generate the key and return immediately, libotr will
> > be very confused.
> > 

That's exactly the way I do it and with current libotr I don't think
there is any other way to do it. The confusion you speak of seems to
disappear quite quickly though once the key has been generated ;)
Although the reason for that might be that I call otrl_privkey_read
after generation (since the key is generated in another process) which
implies IIRC otrl_privkey_forget_all().

> > 
> > So: even assuming we do the above, your create_privkey callback *must
> > not* return until the key generation is complete.  You can still perform
> > the key generation in a subthread, though, and your main thread can
> > handle UI events to avoid appearing frozen, but it *must not* call
> > any libotr functions (even in the UI handlers, hmm).

That is really not an option at all. To give an example on the WLAN
router of a friend of mine key generation takes more than an hour. Now
should one use different keys for different IM networks that would
really induce an inacceptable downtime. On my PC it takes about 6
minutes (unless I do du / or something) and even then it would really
annoy me if I'd loose messages during that time.

I had a look at libotr-3.1.0 message.c:755 and I don't see why libotr
should be confused if create_privkey() doesn't generate a key. Won't
otrl_privkey_find just return NULL in line 758 and we're back in the
same code path as when ops->create_privkey is not implemented? There
won't be a private conversation till a key is available but that is
probably to be expected ;)

Uli




More information about the OTR-dev mailing list