callbacks: application context

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

callbacks: application context

Claus Assmann
I'm trying to implement TLS client side session caching, but I'm
running into problems with the OpenSSL callback API. It seems most
callbacks don't pass an application context which makes using them
awkward (at least in my application that doesn't have global
variables).  SSL_CTX_set_cert_verify_callback(3) allows to pass an
application context:

void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
        int (*callback)(X509_STORE_CTX *,void *), void *arg);

However, functions like:

void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
      int (*new_session_cb)(SSL *, SSL_SESSION *));
void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
        void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *));
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
        int (*verify_callback)(int, X509_STORE_CTX *));

don't offer this. It seems the official way to use an application
context is via:

int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
       CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
int SSL_set_ex_data(SSL *ssl, int idx, void *arg);
void *SSL_get_ex_data(const SSL *ssl, int idx);

However, that still requires a global variable (for idx) as the
example for SSL_CTX_set_verify(3) shows.

Is there some other API (or some "trick") that does not rely
on a global variable?
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Victor Duchovni
On Sun, Mar 20, 2011 at 10:42:28AM -0700, Claus Assmann wrote:

> It seems the official way to use an application
> context is via:
>
> int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
>        CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
> int SSL_set_ex_data(SSL *ssl, int idx, void *arg);
> void *SSL_get_ex_data(const SSL *ssl, int idx);
>
> However, that still requires a global variable (for idx) as the
> example for SSL_CTX_set_verify(3) shows.
>
> Is there some other API (or some "trick") that does not rely
> on a global variable?

What's the obstacle to a global variable that is initialized once and
never changes? You also only need to call:

        SSL_load_error_strings();
        OpenSSL_add_ssl_algorithms();

once, ... so there needs to be some once-only code in your application,
and setting a write-once global there does not seem burdensome.

I am not aware of any other mechanism for passing application context
into the session callback routines.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Graham Leggett
On 20 Mar 2011, at 9:35 PM, Victor Duchovni wrote:

> What's the obstacle to a global variable that is initialized once and
> never changes? You also only need to call:
>
> SSL_load_error_strings();
>        OpenSSL_add_ssl_algorithms();
>
> once, ... so there needs to be some once-only code in your  
> application,
> and setting a write-once global there does not seem burdensome.

It is a showstopper for many asynchronous applications, where the same  
process attempts to keep track of multiple contexts in parallel. The  
lack of a callback makes this very difficult.

Regards,
Graham
--

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Claus Assmann
In reply to this post by Victor Duchovni
On Sun, Mar 20, 2011, Victor Duchovni wrote:

> once, ... so there needs to be some once-only code in your application,

That's trivial to do and already working fine.

> and setting a write-once global there does not seem burdensome.

As Graham points out it makes it hard for some applications to use
multiple contexts. In my case I have libraries that implement server
side and client side, and I want to be able to run them in separate
processes or in a common process. In the latter case having global
variables makes the implementation more complex than it should be.

> I am not aware of any other mechanism for passing application context
> into the session callback routines.

Thanks for the information! So I'll either have to find a way to
implement this without callbacks (might not be possible...) or use
some dirty tricks to deal with the global variables that OpenSSL's
API requires.

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Victor Duchovni
On Sun, Mar 20, 2011 at 07:13:18PM -0700, Claus Assmann wrote:

> On Sun, Mar 20, 2011, Victor Duchovni wrote:
>
> > once, ... so there needs to be some once-only code in your application,
>
> That's trivial to do and already working fine.
>
> > and setting a write-once global there does not seem burdensome.
>
> As Graham points out it makes it hard for some applications to use
> multiple contexts.

There is no problem with multiple contexts, all the complexity is in
initializing multiple "index" values, so that sessions can carry bits
of information from multiple layers of the application.

> In my case I have libraries that implement server
> side and client side, and I want to be able to run them in separate
> processes or in a common process. In the latter case having global
> variables makes the implementation more complex than it should be.

I don't see the difficulty, you can have as many contexts as you want,
none of them global, what's global is the "index" number used to save
a given context into the session. You initialize as many different
indices as you when the application starts. If the same session is
never both a server and a client session, you can even use a single
index, and tag the type of the structure saved at that index as
either a server or client context.

Can you explain a bit more clearly why you can't initialize an
integer index or two when the application starts?

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Claus Assmann
On Mon, Mar 21, 2011, Victor Duchovni wrote:

> Can you explain a bit more clearly why you can't initialize an
> integer index or two when the application starts?

I can, but that's not the problem.  Here's an example:
initialize:
SSL_load_error_strings(); ...
ssl_ctx = SSL_CTX_new();
myidx = SSL_CTX_get_ex_new_index();

set up and start two client instances:
a_ctx1->a_ssl_ctx = ssl_ctx;
a_ctx2->a_ssl_ctx = ssl_ctx;
client(a_ctx1);
client(a_ctx2);
(as threads so they run concurrently)

client() has some code like this:
  SSL_CTX_set_ex_data(a_ctx->a_ssl_ctx, myidx, a_ctx->cb_arg);
which means the "last call wins" to actually sets the application
context for SSL_CTX, right?
Hence doing something like this:
  SSL_CTX_set_info_callback(a_ctx->a_ssl_ctx, clt_cb)
where clt_cb(SSL_CTX *ssl_ctx) retrieves the application context via:
  cb_arg = (cast...) SSL_CTX_get_ex_data(ssl_ctx, myidx);
will get some "random" application context.


However, the API works ok if:
- different SSL_CTXs are used
- callbacks are only set for SSL which are different for each
  client() invocation anyway.

This means for the common use case the method should work properly.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Victor Duchovni
On Mon, Mar 21, 2011 at 08:49:09PM -0700, Claus Assmann wrote:

> On Mon, Mar 21, 2011, Victor Duchovni wrote:
>
> > Can you explain a bit more clearly why you can't initialize an
> > integer index or two when the application starts?
>
> I can, but that's not the problem.  Here's an example:
> initialize:
> SSL_load_error_strings(); ...
> ssl_ctx = SSL_CTX_new();
> myidx = SSL_CTX_get_ex_new_index();
>
> set up and start two client instances:
> a_ctx1->a_ssl_ctx = ssl_ctx;
> a_ctx2->a_ssl_ctx = ssl_ctx;
> client(a_ctx1);
> client(a_ctx2);
> (as threads so they run concurrently)
>
> client() has some code like this:
>   SSL_CTX_set_ex_data(a_ctx->a_ssl_ctx, myidx, a_ctx->cb_arg);

No, don't do that, the SSL_CTX application context object is global.
Why do you want to tweak it the context of an individual connection.

You should be modifying the SSL object, not the SSL_CTX object. Postfix
has:

    SSL_set_ex_data(TLScontext->con, TLScontext_index, TLScontext)

> which means the "last call wins" to actually sets the application
> context for SSL_CTX, right?

Yes, but what are you trying to do? The SSL_CTX is clearly shared
application state, not per-session state.

> However, the API works ok if:
> - different SSL_CTXs are used
> - callbacks are only set for SSL which are different for each
>   client() invocation anyway.
>
> This means for the common use case the method should work properly.

So, what's the problem?

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Claus Assmann
On Tue, Mar 22, 2011, Victor Duchovni wrote:

> > client() has some code like this:
> >   SSL_CTX_set_ex_data(a_ctx->a_ssl_ctx, myidx, a_ctx->cb_arg);
>
> No, don't do that, the SSL_CTX application context object is global.

I was demonstrating that the callback API has some problems.
If the common(?) way of taking a user supplied argument would be
used then things would be simpler for application programmers, as
can be seen by SSL_CTX_set_cert_verify_callback(3).

Anyway, thanks for pointing out that these things can be done
differently; now I'll have to figure out whether my current TLS
client session caching prototype that I just wrote to work without
callbacks is incorrect.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: callbacks: application context

Victor Duchovni
On Tue, Mar 22, 2011 at 08:47:55PM -0700, Claus Assmann wrote:

> On Tue, Mar 22, 2011, Victor Duchovni wrote:
>
> > > client() has some code like this:
> > >   SSL_CTX_set_ex_data(a_ctx->a_ssl_ctx, myidx, a_ctx->cb_arg);
> >
> > No, don't do that, the SSL_CTX application context object is global.
>
> I was demonstrating that the callback API has some problems.

Well, two different ways of handling application context in callbacks,
but neither is fatally flawed. There is some sanity here, as sessions
are complicated beasts, that can potentially be decorated with multiple
bits of context as the same session gets used in multiple ways, while
only one "master" can be responsible for certificate verification at a time.

The difference in the API is perhaps not entirely capricious.

--
        Viktor.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]