Subject: Re: Comments on the SASL C API

From: Greg Hudson <[email-masked]>
Date: Sun, 29 Jun 2003 15:36:22 -0400

On 29 Jun 2003 19:15:31 +0200, Simon Josefsson wrote:
> int sasl_decode(sasl_conn_t *conn,
>             const char *input,
>             unsigned int inputlen,
>             const char **output,
>             unsigned int *outputlen);

> Consider what happens if the input/inputlen fields of the
> sasl_decode() contains two tokens from sasl_encode(), or one SASL
> token and a few bytes of the next SASL token.

Presumably it is the responsibility of the sasl_decode()
implementation to remember (using state associated with conn) the
partial bytes.  If there are two or more tokens in input, the
resulting output tokens can presumably be concatenated together; I
don't think applications are supposed to rely on knowing anything
about the security later's framing.

> This require that mechanisms are able to figure this information
> out, and looking at e.g. DIGEST-MD5 I'm not sure this is the case.
> How does DIGEST-MD5 decode() know that a SASL encode token ends?
> Some framing seem to be required.  I may be missing something, even
> though I have implemented this, and can't recall how this problem is
> solved in my implementation.

RFC 2222 states:

   Once the security layer is in effect, the protocol stream is
   processed by the security layer into buffers of cipher-text.  Each
   buffer is transferred over the connection as a stream of octets
   prepended with a four octet field in network byte order that
   represents the length of the following buffer.

---

From: Lawrence Greenfield <[email-masked]>
Date: Sun, 29 Jun 2003 19:02:58 -0400

Date: Sun, 29 Jun 2003 15:36:22 -0400
   From: Greg Hudson <[email-masked]>

That is correct. Because of the limitations on the buffer sizes, the
SASL library can always save this "intermediate" state in a constant
amount of space (at most the max SASL token size).

I believe it's more efficient for the library to do this than
requiring the application to "remember" unconsumed encoded data. It is
also less error prone for application programmers.

The Cyrus SASL documentation has the following hints. If both sides
follow these guidelines---or their equivalent---you get efficient
communication.

* Before starting authentication, set maxbufsize in your security
  properties to be the buffer size that you pass to the read() system
  call---that is, the amount of data you're prepared to read at any
  one time.

* After authentication finishes, use sasl_getprop() to retrieve the
  SASL_MAXOUTBUF value, and call sasl_encode() with chunks of data of
  that size or less. sasl_encode() will throw an error if you call it
  with a larger chunk of data, so be careful!

Larry

---

From: Lawrence Greenfield <[email-masked]>
Date: Sun, 29 Jun 2003 19:02:58 -0400

Larry