This change allows a callback to be used to override the generation of

SSL/TLS session IDs in a server. According to RFC2246, the session ID is an
arbitrary value chosen by the server. It can be useful to have some control
over this "arbitrary value" so as to choose it in ways that can aid in
things like external session caching and balancing (eg. clustering). The
default session ID generation is to fill the ID with random data.

The callback used by default is built in to ssl_sess.c, but registering a
callback in an SSL_CTX or in a particular SSL overrides this. BTW: SSL
callbacks will override SSL_CTX callbacks, and a new SSL structure inherits
any callback set in its 'parent' SSL_CTX. The header comments describe how
this mechanism ticks, and source code comments describe (hopefully) why it
ticks the way it does.

Man pages are on the way ...

[NB: Lutz was also hacking away and helping me to figure out how best to do
this.]
This commit is contained in:
Geoff Thorpe
2001-02-21 18:06:26 +00:00
parent 47ddf355b4
commit dc644fe229
5 changed files with 150 additions and 18 deletions

View File

@@ -218,6 +218,7 @@ SSL *SSL_new(SSL_CTX *ctx)
s->verify_mode=ctx->verify_mode;
s->verify_depth=ctx->verify_depth;
s->verify_callback=ctx->default_verify_callback;
s->generate_session_id=ctx->generate_session_id;
s->purpose = ctx->purpose;
s->trust = ctx->trust;
CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
@@ -282,6 +283,41 @@ int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
return 1;
}
int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
{
CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
ctx->generate_session_id = cb;
CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
return 1;
}
int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
{
CRYPTO_w_lock(CRYPTO_LOCK_SSL);
ssl->generate_session_id = cb;
CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
return 1;
}
int SSL_CTX_has_matching_session_id(const SSL_CTX *ctx, const unsigned char *id,
unsigned int id_len)
{
/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
* we can "construct" a session to give us the desired check - ie. to
* find if there's a session in the hash table that would conflict with
* any new session built out of this id/id_len and the ssl_version in
* use by this SSL_CTX. */
SSL_SESSION r, *p;
r.ssl_version = ctx->method->version;
r.session_id_length = id_len;
memcpy(r.session_id, id, id_len);
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
p = (SSL_SESSION *)lh_retrieve(ctx->sessions, &r);
CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
return (p != NULL);
}
int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
{
if(X509_PURPOSE_get_by_id(purpose) == -1) {
@@ -1092,6 +1128,11 @@ unsigned long SSL_SESSION_hash(SSL_SESSION *a)
return(l);
}
/* NB: If this function (or indeed the hash function which uses a sort of
* coarser function than this one) is changed, ensure
* SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
* able to construct an SSL_SESSION that will collide with any existing session
* with a matching session ID. */
int SSL_SESSION_cmp(SSL_SESSION *a,SSL_SESSION *b)
{
if (a->ssl_version != b->ssl_version)
@@ -1143,6 +1184,7 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
ret->new_session_cb=NULL;
ret->remove_session_cb=NULL;
ret->get_session_cb=NULL;
ret->generate_session_id=NULL;
memset((char *)&ret->stats,0,sizeof(ret->stats));