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:
@@ -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));
|
||||
|
||||
|
Reference in New Issue
Block a user